From: Snapshot-Content-Location: https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#VkBufferCreateFlagBits Subject: =?utf-8?Q?Vulkan=C2=AE 1.1.82 - A Specification (with all published extensions)?= Date: Sun, 29 Sep 2018 06:32:30 -0000 MIME-Version: 1.0 Content-Type: multipart/related; type="text/html"; boundary="----MultipartBoundary--qLVjWd2mJZuVXpZ7T5d8aGIIY8W483Ad8cFONoagZS----" ------MultipartBoundary--qLVjWd2mJZuVXpZ7T5d8aGIIY8W483Ad8cFONoagZS---- Content-Type: text/html Content-ID: Content-Transfer-Encoding: quoted-printable Content-Location: https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#VkBufferCreateFlagBits Vulkan=C2=AE 1.1.82 - A Specification (with all published extensions= )

Vulkan=C2=AE 1.1.82 - A Specification (with all published ex= tensions)

The Khronos Vulkan Working Group
version 1.1.82, 2018-07-30 22:05:23Z
from git branch: master commit: ff0c2339083b76ab= a0414afafdb195bba15c78d8
Table of Contents

Copyright 2014-2018 The Khronos Group Inc.

This Specification is protected by copyright laws and contains material proprietary to Khronos. Except as described by these terms, it or any components may not be reproduced, republished, distributed, transmitted, displayed, broadcast or otherwise exploited in any manner without the express prior written permission of Khronos. Khronos grants a conditional copyright license to use and reproduce the unmodified Specification for any purpose, without fee or royalty, EXCEPT no licenses to any patent, trademark or other intellectual property rights are granted under these terms.

Khronos makes no, and expressly disclaims any, representations or warranties, express or implied, regarding this Specification, including, without limitation: merchantability, fitness for a particular purpose, non-infringement of any intellectual property, correctness, accuracy, completeness, timeliness, and reliability. Under no circumstances will Khronos, or any of its Promoters, Contributors or Members, or their respective partners, officers, directors, employees, agents or representatives be liable for any damages, whether direct, indirect, special or consequential damages for lost revenues, lost profits, or otherwise, arising from or in connection with these materials.

This Specification has been created under the Khronos Intellectual Prope= rty Rights Policy, which is Attachment A of the Khronos Group Membership Agreement available at www.khronos.org/files/member_agreement.pdf, and whic= h defines the terms 'Scope', 'Compliant Portion', and 'Necessary Patent Claim= s'. Parties desiring to implement the Specification and make use of Khronos tra= demarks in relation to that implementation, and receive reciprocal patent license p= rotection under the Khronos Intellectual Property Rights Policy must become Adopters = and confirm the implementation as conformant under the process defined by Khron= os for this Specification; see https://www.khronos.org/adopters.

This Specification contains substantially unmodified functionality from,= and is a successor to, Khronos specifications including OpenGL, OpenGL ES and OpenCL= .

Some parts of this Specification are purely informative and so are EXCLU= DED from the Scope of this Specification. The Document Con= ventions section of the Introduction defines how these parts of the Specification= are identified.

Where this Specification uses techni= cal terminology, defined in the Glossary or otherwise, that r= efer to enabling technologies that are not expressly set forth in this Specification, those enabling technologies are EXCLUDED from the Scope of this Specification. For clarity, enabling technologies not disclosed with particularity in this Specification (e.g. semiconductor manufacturing technology, hardware architecture, processor architecture or microarchitecture, memory architecture, compiler technology, object oriented technology, basic operating system technology, compression technology, algorithms, and so on) are NOT to be considered expressly set forth; only those application progra= m interfaces and data structures disclosed with particularity are included in the Scope of this Specification.

For purposes of the Khronos Intellectual Property Rights Policy as it re= lates to the definition of Necessary Patent Claims, all recommended or optional features, behaviors and functionality set forth in this Specification, if implemented, are considered to be included as Compliant Portions.

Where this Specification includes nor= mative references to external documents, only the specifically identified sections of those external documents are INCLUDED in the Scope o= f this Specification. If not created by Khronos, those external documents may contain contributions from non-members of Khronos not covered by the Khrono= s Intellectual Property Rights Policy.

This document contains extensions which are not ratified by Khronos, and= as such is not a ratified Specification, though it contains text from (and is = a superset of) the ratified Vulkan Specification. The ratified versions of th= e Vulkan Specification can be found at https://www.khronos.org/registry/vulkan/specs/1.1/html/v= kspec.html (core only) and https://www.khronos.org/registry/vulkan/s= pecs/1.1-khr_extensions/html/vkspec.html (core with KHR extensions).

Vulkan is a registered trademark, and Khronos is a trademark of The Khro= nos Group Inc. ASTC is a trademark of ARM Holdings PLC; OpenCL is a trademark o= f Apple Inc.; and OpenGL is a registered trademark of Silicon Graphics Intern= ational, all used under license by Khronos. All other product names, trademarks, and= /or company names are used solely for identification and belong to their respec= tive owners.

1. Introduction

This document, referred to as the =E2=80=9CVulkan Specification=E2=80=9D= or just the =E2=80=9CSpecification=E2=80=9D hereafter, describes the Vulkan Application= Programming Interface (API). Vulkan is a C99 API designed for explicit control of low-level graphics and compute functionality.

The canonical version of the Specification is available in the official Vulkan Registry (http://= www.khronos.org/registry/vulkan/). The source files used to generate the Vulkan specification are stored in th= e Vulkan Documentatio= n Repository (htt= ps://github.com/KhronosGroup/Vulkan-Docs). The source repository additionally has a public issue tracker and allows th= e submission of pull requests that improve the specification.

1.1. Document Conventions

The Vulkan specification is intended for use by both implementors of the= API and application developers seeking to make use of the API, forming a contract between these parties. Specification text may address either party; typically the intended audienc= e can be inferred from context, though some sections are defined to address only one of these parties. (For example, Valid Usage sections only addres= s application developers). Any requirements, prohibitions, recommendations or options defined by normative terminology are imposed only on the audience of that text.

Note

Structure and enumerated types defined in extensions that were promoted = to core in Vulkan 1.1 are now defined in terms of the equivalent Vulkan 1.1 interfaces. This affects the Vulkan Specification, the Vulkan header files, and the corresponding XML Registry.

1.1.1. Normative Terminology<= /h4>

Within this specification, the key words must, = required, should, recommended, may, and optional are to be interpreted as described in RFC 2119 - Key words for us= e in RFCs to Indicate Requirement Levels (http://www.ietf.org/rfc/rfc2119.txt). These key words are highlighted in the specification for clarity. In text addressing application developers, their use expresses requirements that apply to application behavior. In text addressing implementors, their use expresses requirements that appl= y to implementations.

In text addressing application developers, the additional key words can and cannot are to be interpreted as describing the capabil= ities of an application, as follows:

can

This word means that the application is able to perform the action described.

cannot

This word means that the API and/or the execution environment provide no mechanism through which the application can express or accomplish the actio= n described.

These key words are never used in text addressing implementors.

Note

There is an important distinction between cannot and must not, as used in this Specification. Cannot means something the application literally is unable= to express or accomplish through the API, while must not means something= that the application is capable of expressing through the API, but that the consequences of doing so are undefined and potentially unrecoverable for th= e implementation.

Unless otherwise noted in the section heading, all sections and appendic= es in this document are normative.

1.1.2. Technical Terminology<= /h4>

The Vulkan Specification makes use of common engineering and graphics te= rms such as Pipeline, Shader, and Hos= t to identify and describe Vulkan API constructs and their attributes, states, and behaviors. The Glossary defines the basic meanings of these terms in the context of the Specification. The Specification text provides fuller definitions of the terms and may elaborate, extend, or clarify the Glossary definitions. When a term defined in the Glossary is used in normative language within the Specification, the definitions within the Specification govern and supersede any meanings the terms may have in other technical contexts (i.e. outside the Specification).

1.1.3. Normative References

References to external documents are considered normative references if = the Specification uses any of the normative terms defined in Normative Terminology to refer to t= hem or their requirements, either as a whole or in part.

The following documents are referenced by normative sections of the specification:

IEEE Standard for Floating-Point Arithmetic, IEEE Std 754-2008, h= ttp://dx.doi.org/10.1109/IEEESTD.2008.4610935, August, 2008.

A. Garrard, Khronos Data Format Specifica= tion, version 1.2, https://www.khronos.org/registry/DataFormat/specs= /1.2/dataformat.1.2.html, September, 2017.

J. Kessenich, SPIR-V Extended Instruct= ions for GLSL, Version 1.00, https://www.khronos.org/registry/spir-v/, February 10, 2016= .

J. Kessenich and B. Ouriel, The Khronos SP= IR-V Specification, Version 1.00, https://www.khronos.org/registry/spir-v/, February 10, 2016.

J. Leech and T. Hector, Vulkan Docu= mentation and Extensions: Procedures and Conventions, https://www.khronos.org/registry/vulkan/specs/1.1/stylegu= ide.html

Vulkan Loader Specification and Architecture Overview, https://github.com/KhronosGroup= /Vulkan-Loader/blob/master/loader/LoaderAndLayerInterface.md, August, 2016.

2. Fundamentals

This chapter introduces fundamental concepts including the Vulkan architecture and execution model, API syntax, queues, pipeline configurations, numeric representation, state and state queries, and the different types of objects and shaders. It provides a framework for interpreting more specific descriptions of commands and behavior in the remainder of the Specification.

2.1. Host and Device Environment

The Vulkan Specification assumes and requires: the following properties = of the host environment with respect to Vulkan implementations:

  • The host must have runtime support for= 8, 16, 32 and 64-bit signed and unsigned twos-complement integers, all addressable at the granularity of their size in bytes.

  • The host must have runtime support for= 32- and 64-bit floating-point types satisfying the range and precision constraints in the Floating Point Computation section.

  • The representation and endianness of these types on the host must match the representation and endianness of the same types on every physical device supported.

Note

Since a variety of data types and structures in Vulkan may be accessible by both host and physical device operations, the implementation should be able to access such data efficiently in both paths in order to facilitate writin= g portable and performant applications.

2.2. Execution Model

This section outlines the execution model of a Vulkan system.

Vulkan exposes one or more devices, each of which exposes one o= r more queues which may process work as= ynchronously to one another. The set of queues supported by a device is partitioned into families. Each family supports one or more types of functionality and may contain multiple queues with similar characteristics. Queues within a single family are considered compatible with one a= nother, and work produced for a family of queues can be executed on any queue within that family. This Specification defines four types of functionality that queues may support: graphics, compute, transfer, and sparse memory management.

Note

A single device may report multiple si= milar queue families rather than, or as well as, reporting multiple members of one or more of those families. This indicates that while members of those families have similar capabilities, they are not directly compatible with one another.

Device memory is explicitly managed by the application. Each device may advertise one or more hea= ps, representing different areas of memory. Memory heaps are either device local or host local, but are always visible to the device. Further detail about memory heaps is exposed via memory types available on that heap. Examples of memory areas that may be avai= lable on an implementation include:

  • device local is memory that is physically connected to the devi= ce.

  • device local, host visible is device local memory that is visib= le to the host.

  • host local, host visible is memory that is local to the host an= d visible to the device and host.

On other architectures, there may only= be a single heap that can be used for any purpose.

A Vulkan application controls a set of devices through the submission of command buffers which have recorded device commands issued via Vulkan library calls. The content of command buffers is specific to the underlying implementation and is opaque to the application. Once constructed, a command buffer can be= submitted once or many times to a queue for execution. Multiple command buffers can be built in = parallel by employing multiple threads within the application.

Command buffers submitted to different queues m= ay execute in parallel or even out of order with respect to one another. Command buffers submitted to a single queue respect submission order, as described furthe= r in synchronization chapter. Command buffer execution by the device is also asynchronous to host execution. Once a command buffer is submitted to a queue, control may return to the application immediately. Synchronization between the device and host, and between different queues i= s the responsibility of the application.

2.2.1. Queue Operation

Vulkan queues provide an interface to the execution engines of a device. Commands for these execution engines are recorded into command buffers ahea= d of execution time. These command buffers are then submitted to queues with a queue submiss= ion command for execution in a number of batches. Once submitted to a queue, these commands will begin and complete execution without further application intervention, though the order of this executio= n is dependent on a number of implicit and explicit ordering constraints.

Work is submitted to queues using queue submission commands that typical= ly take the form vkQueue* (e.g. vkQueueSubmit, vkQueueBindSparse), and optionally take a list of se= maphores upon which to wait before work begins and a list of semaphores to signal once work has completed. The work itself, as well as signaling and waiting on the semaphores are all queue operations.

Queue operations on different queues have no implicit ordering constrain= ts, and may execute in any order. Explicit ordering constraints between queues can be expressed with semaphores and fences.

Command buffer submissions to a single queue respect submission order and other implicit ordering guarantees, but otherwise may overlap or execute out of order. Other types of batches and queue submissions against a single queue (e.g. sparse memory binding) have no implicit ordering constraints with any other queue submission or batch. Additional explicit ordering constraints between queue submissions and individual batches can be expressed with semaphores and fences.

Before a fence or semaphore is signaled, it is guaranteed that any previously submitted queue operations have completed execution, and that memory writes from those queue operations are available to future queue operations. Waiting on a signaled semaphore or fence guarantees that previous writes that are available are also visible to subseque= nt commands.

Command buffer boundaries, both between primary command buffers of the s= ame or different batches or submissions as well as between primary and secondar= y command buffers, do not introduce any additional ordering constraints. In other words, submitting the set of command buffers (which can include executing secondary command buffers) between any semaphore or fence operations execute the recorded commands as if they had all been recorded into a single primary command buffer, except that the current state is reset on each boundary. Explicit ordering constraints can be expr= essed with explicit synchronization primitives.

Note

Implementations have significant freedom to overlap execution of work submitted to a queue, and this is common due to deep pipelining and parallelism in Vulkan devices.

Commands recorded in command buffers either perform actions (draw, dispa= tch, clear, copy, query/timestamp operations, begin/end subpass operations), set state (bind pipelines, descriptor sets, and buffers, set dynamic state, pus= h constants, set render pass/subpass state), or perform synchronization (set/wait events, pipeline barrier, render pass/subpass dependencies). Some commands perform more than one of these tasks. State setting commands update the current state of the command buf= fer. Some commands that perform actions (e.g. draw/dispatch) do so based on the current state set cumulatively since the start of the command buffer. The work involved in performing action commands is often allowed to overlap or to be reordered, but doing so must not= alter the state to be used by each action command. In general, action commands are those commands that alter framebuffer attachments, read/write buffer or image memory, or write to query pools.

Synchronization commands introduce explicit execution and memory dependencies between two sets of action commands, where the second set of commands depends on th= e first set of commands. These dependencies enforce that both the execution of certain pipeline stages in the later set occur after the execution of certain stages in the source set, and that the effects of memory accesses performed by certain pipeline stages occur in order and are visible to each other. When not enforced by an explicit dependency or im= plicit ordering guarantees, action commands ma= y overlap execution or execute out of order, and may not see the= side effects of each other=E2=80=99s memory accesses.

The device executes queue operations asynchronously with respect to the host. Control is returned to an application immediately following command buffer submission to a queue. The application must synchronize work bet= ween the host and device as needed.

2.3. Object Model

The devices, queues, and other entities in Vulkan are represented by Vul= kan objects. At the API level, all objects are referred to by handles. There are two classes of handles, dispatchable and non-dispatchable. Dispatchable handle types are a pointer to an opaque type. This pointer may be used by layers as par= t of intercepting API commands, and thus each API command takes a dispatchable type as its first parameter. Each object of a dispatchable type must h= ave a unique handle value during its lifetime.

Non-dispatchable handle types are a 64-bit integer type whose m= eaning is implementation-dependent, and may encode = object information directly in the handle rather than acting as a reference to an underlying object. Objects of a non-dispatchable type may no= t have unique handle values within a type or across types. If handle values are not unique, then destroying one such handle must not cause identical handles of other types to become invalid, and must not cause identical handles of the same type to become invalid if that handle value has been created more times than it has been destroyed.

All objects created or allocated from a VkDevice (i.e. with= a VkDevice as the first parameter) are private to that device, a= nd must not be used on other devices.

2.3.1. Object Lifetime

Objects are created or allocated by vkCreate* and vkA= llocate* commands, respectively. Once an object is created or allocated, its =E2=80=9Cstructure=E2=80=9D is = considered to be immutable, though the contents of certain object types is still free to change. Objects are destroyed or freed by vkDestroy* and vkFree*= commands, respectively.

Objects that are allocated (rather than created) take resources from an existing pool object or memory heap, and when freed return resources to tha= t pool or heap. While object creation and destruction are generally expected to be low-frequency occurrences during runtime, allocating and freeing objects can occur at high frequency. Pool objects help accommodate improved performance of the allocations and frees.

It is an application=E2=80=99s responsibility to track the lifetime of V= ulkan objects, and not to destroy them while they are still in use.

The ownership of application-owned memory is immediately acquired by any Vulkan command it is passed into. Ownership of such memory must be released= back to the application at the end of the duration of the command, so that the application can alter or free this memory as soon as all the commands that acquired it have returned= .

The following object types are consumed when they are passed into a Vulk= an command and not further accessed by the objects they are used to create. They must not be destroyed in the duratio= n of any API command they are passed into:

  • VkShaderModule

  • VkPipelineCache

  • VkValidationCacheEXT

A VkRenderPass object passed as a parameter to create anoth= er object is not further accessed by that object after the duration of the command it is passed into. A VkRenderPass used in a command buffer follows the rules desc= ribed below.

A VkPipelineLayout object must not be destroyed while any command buffer that uses it is in the recording state.

VkDescriptorSetLayout objects may<= /strong> be accessed by commands that operate on descriptor sets allocated using that layout, and those descripto= r sets must not be updated with vkUpdateDescriptorSets after the descriptor set layout has been destroyed. Otherwise, a VkDescriptorSetLayout object passed as a paramete= r to create another object is not further accessed by that object after the duration of the command it is passed into.

The application must not destroy any o= ther type of Vulkan object until all uses of that object by the device (such as via command buffer execution) have completed.

The following Vulkan objects must not = be destroyed while any command buffers using the object are in the pending state:

  • VkEvent

  • VkQueryPool

  • VkBuffer

  • VkBufferView

  • VkImage

  • VkImageView

  • VkPipeline

  • VkSampler

  • VkSamplerYcbcrConversion

  • VkDescriptorPool

  • VkFramebuffer

  • VkRenderPass

  • VkCommandBuffer

  • VkCommandPool

  • VkDeviceMemory

  • VkDescriptorSet

  • VkObjectTableNVX

  • VkIndirectCommandsLayout

Destroying these objects will move any command buffers that are in the recording or executable state, and are using those objects, to the invalid state.

The following Vulkan objects must not = be destroyed while any queue is executing commands that use the object:

  • VkFence

  • VkSemaphore

  • VkCommandBuffer

  • VkCommandPool

In general, objects can be destroyed o= r freed in any order, even if the object being freed is involved in the use of another object (e.g. use of a resource in a view, use of a view in a descriptor set, use of an object in = a command buffer, binding of a memory allocation to a resource), as long as any object that uses the freed object is not further used in any way except to be destroyed or to be reset in such a way that it no longer uses the other object (such as resetting a command buffer). If the object has been reset, then it can= be used as if it never used the freed object. An exception to this is when there is a parent/child relationship between objects. In this case, the application must not de= stroy a parent object before its children, except when the parent is explicitly defined to free its children when it is destroyed (e.g. for pool objects, as defined below).

VkCommandPool objects are parents of VkCommandBuffer<= /code> objects. VkDescriptorPool objects are parents of VkDescriptorSet<= /code> objects. VkDevice objects are parents of many object types (all that ta= ke a VkDevice as a parameter to their creation).

The following Vulkan objects have specific restrictions for when they can be destroyed:

  • VkQueue objects cannot be= explicitly destroyed. Instead, they are implicitly destroyed when the VkDevice objec= t they are retrieved from is destroyed.

  • Destroying a pool object implicitly frees all objects allocated from that pool. Specifically, destroying VkCommandPool frees all VkCommandBuffer objects that were allocated from it, and destroying VkDescriptorPool frees all VkDescriptorSet objects that were allocated from it.

  • VkDevice objects can be d= estroyed when all VkQueue objects retrieved from them are idle, and all objects created from them have been destroyed. This includes the following objects:

    • VkFence

    • VkSemaphore

    • VkEvent

    • VkQueryPool

    • VkBuffer

    • VkBufferView

    • VkImage

    • VkImageView

    • VkShaderModule

    • VkPipelineCache

    • VkPipeline

    • VkPipelineLayout

    • VkSampler

    • VkSamplerYcbcrConversion

    • VkDescriptorSetLayout

    • VkDescriptorPool

    • VkFramebuffer

    • VkRenderPass

    • VkCommandPool

    • VkCommandBuffer

    • VkDeviceMemory

  • VkValidationCacheEXT

  • VkPhysicalDevice objects cannot be explicitly destroyed. Instead, they are implicitly destroyed when the VkInstance obj= ect they are retrieved from is destroyed.

  • VkInstance objects can be= destroyed once all VkDevice objects created from any of its VkPhysicalDevice objects have = been destroyed.

2.3.2. External Object Handles=

As defined above, the scope of object handles created or allocated from = a VkDevice is limited to that logical device. Objects which are not in scope are said to be external. To bring an external object into scope, an external handle must be exported from the object in the source scope and imported into the destination scope= .

Note

The scope of external handles and their associated resources may vary according to their type, but they can gen= erally be shared across process and API boundaries.

2.4. Application Binary Interface

The mechanism by which Vulkan is made available to applications is platf= orm- or implementation- defined. On many platforms the C interface described in this Specification is provided by a shared library. Since shared libraries can be changed independently of the applications tha= t use them, they present particular compatibility challenges, and this Specification places some requirements on them.

Shared library implementations must us= e the default Application Binary Interface (ABI) of the standard C compiler for the platform, or provide customized API headers that cause application code to use the implementation=E2=80=99s non-default ABI. An ABI in this context means the size, alignment, and layout of C data types; the procedure calling convention; and the naming convention for shared library symbols corresponding to C functions. Customizing the calling convention for a platform is usually accomplished b= y defining calling convention macros appropriately in vk_platform.h.

On platforms where Vulkan is provided as a shared library, library symbo= ls beginning with =E2=80=9Cvk=E2=80=9D and followed by a digit or uppercase le= tter are reserved for use by the implementation. Applications which use Vulkan must not pr= ovide definitions of these symbols. This allows the Vulkan shared library to be updated with additional symbols for new API versions or extensions without causing symbol conflicts with existing applications.

Shared library implementations should = provide library symbols for commands in the highest version of this Specification they support, and for Window System Integration extensions relevant to the platform. They may also provide library symbols for= commands defined by additional extensions.

Note

These requirements and recommendations are intended to allow implementor= s to take advantage of platform-specific conventions for SDKs, ABIs, library versioning mechanisms, etc. while still minimizing the code changes necessary to port applications or libraries between platforms. Platform vendors, or providers of the de facto standard Vulkan sha= red library for a platform, are encouraged to document what symbols the shared library provides and how it will be versioned when new symbols are added.

Applications should only rely on share= d library symbols for commands in the minimum core version required by the application. vkGetInstanceProcAddr and v= kGetDeviceProcAddr should be used to obtain function pointers for commands in core versions beyond the application=E2=80=99s minimum required version.

2.5. Command Syntax and Duration

The Specification describes Vulkan commands as functions or procedures u= sing C99 syntax. Language bindings for other languages such as C++ and JavaScript may allow for stricter parameter passing, or object-oriented interfaces.

Vulkan uses the standard C types for the base type of scalar parameters (e.g. types from <stdint.h>), with exceptions described = below, or elsewhere in the text when appropriate:

VkBool32 represents boolean True and Fal= se values, since C does not have a sufficiently portable built-in boolean type:

typedef uint32_t VkBool32;

VK_TRUE represents a boolean True (integer= 1) value, and VK_FALSE a boolean False (integer 0) value.

All values returned from a Vulkan implementation in a VkBool32 will be either VK_TRUE or VK_FALSE.

Applications must not pass any other v= alues than VK_TRUE or VK_FALSE into a Vulkan implementation where a VkBool32 is expected.

VkDeviceSize represents device memory size and offset value= s:

typedef uint64_t VkDeviceSize;

Commands that create Vulkan objects are of the form vkCreate* and take Vk*CreateInfo structures with the parameters needed to create = the object. These Vulkan objects are destroyed with commands of the form vkDestroy*.

The last in-parameter to each command that creates or destroys a Vulkan object is pAllocator. The pAllocator parameter can= be set to a non-NULL value such that allocations for the given object are delegated to an application provided callback; refer to the Memory Allocation chapter for further details.

Commands that allocate Vulkan objects owned by pool objects are of the f= orm vkAllocate*, and take Vk*AllocateInfo structures. These Vulkan objects are freed with commands of the form vkFree*. These objects do not take allocators; if host memory is needed, they will use the allocator that was specified when their parent pool was created.

Commands are recorded into a command buffer by calling API commands of t= he form vkCmd*. Each such command may have different rest= rictions on where it can be used: in a primary and/or secondary command buffer, inside and/or outside a rende= r pass, and in one or more of the supported queue types. These restrictions are documented together with the definition of each such command.

The duration of a Vulkan command refers to the interval between= calling the command and its return to the caller.

2.5.1. Lifetime of R= etrieved Results

Information is retrieved from the implementation with commands of the fo= rm vkGet* and vkEnumerate*.

Unless otherwise specified for an individual command, the results are invariant; that is, they will remain unchanged when retrieved agai= n by calling the same command with the same parameters, so long as those parameters themselves all remain valid.

2.6. Threading Behavior

Vulkan is intended to provide scalable performance when used on multiple host threads. All commands support being called concurrently from multiple threads, but certain parameters, or components of parameters are defined to be externally synchronized. This means that the caller must guarantee= that no more than one thread is using such a parameter at a given time.

More precisely, Vulkan commands use simple stores to update the state of Vulkan objects. A parameter declared as externally synchronized ma= y have its contents updated at any time during the host execution of the command. If two commands operate on the same object and at least one of the commands declares the object to be externally synchronized, then the caller must guarantee not only that the commands do not execute simultaneously, but als= o that the two commands are separated by an appropriate memory barrier (if needed).

Note

Memory barriers are particularly relevant for hosts based on the ARM CPU architecture, which is more weakly ordered than many developers are accustomed to from x86/x64 programming. Fortunately, most higher-level synchronization primitives (like the pthread library) perform memory barriers as a part of mutual exclusion, so mutexing Vulkan objects via these primitives will have the desired effect.

Many object types are immutable, meaning the objects cannot change once they have been created. These types of objects never need external synchronization, except that the= y must not be destroyed while they are in u= se on another thread. In certain special cases mutable object parameters are internally synchronized, making external synchronization unnecessary. One example of this is the use of a VkPipelineCache in vkCreateGraphicsPipelines and vkCreateComputePipelines, where external synchronization around such a heavyweight command would be impractical. The implementation must internally synchr= onize the cache in this example, and may be able to do so in the form of a= much finer-grained mutex around the command. Any command parameters that are not labeled as externally synchronized are either not mutated by the command or are internally synchronized. Additionally, certain objects related to a command=E2=80=99s parameters (e.= g. command pools and descriptor pools) may b= e affected by a command, and must also be externally synchronized. These implicit parameters are documented as described below.

Parameters of commands that are externally synchronized are listed below= .

Externally Synchronized Parameters

There are also a few instances where a command = can take in a user allocated list whose contents are externally synchronized parameters. In these cases, the caller must guarantee= that at most one thread is using a given element within the list at a given time. These parameters are listed below.

Externally Synchronized Parameter Lists

In addition, there are some implicit parameters that need to be external= ly synchronized. For example, all commandBuffer parameters that need to be exte= rnally synchronized imply that the commandPool that was passed in whe= n creating that command buffer also needs to be externally synchronized. The implicit parameters and their associated object are listed below.

Implicit Externally Synchronized Parameters

2.7. Errors

Vulkan is a layered API. The lowest layer is the core Vulkan layer, as defined by this Specification= . The application can use additional layers= above the core for debugging, validation, and other purposes.

One of the core principles of Vulkan is that building and submitting com= mand buffers should be highly efficient. Thus error checking and validation of state in the core layer is minimal, although more rigorous validation can be = enabled through the use of layers.

The core layer assumes applications are using the API correctly. Except as documented elsewhere in the Specification, the behavior of the core layer to an application using the API incorrectly is undefined, and may include program termination. However, implementations must ensure that= incorrect usage by an application does not affect the integrity of the operating system, the Vulkan implementation, or other Vulkan client applications in the system. In particular, any guarantees made by an operating system about whether memory from one process can be visible to= another process or not must not be violated by a Vulkan implementation for any memory allocation. Vulkan implementations are not required t= o make additional security or integrity guarantees beyond those provided by the OS unless explicitly directed by the application=E2=80=99s use of a particular feature or extens= ion (e.g. via robust buffer access).

Note

For instance, if an operating system guarantees that data in all its mem= ory allocations are set to zero when newly allocated, the Vulkan implementation must make the same guarantees for any all= ocations it controls (e.g. VkDeviceMemory).

Applications can request stronger robu= stness guarantees by enabling the robustBufferAccess feature as described in Features,= Limits, and Formats.

Validation of correct API usage is left to validation layers. Applications should be developed with val= idation layers enabled, to help catch and eliminate errors. Once validated, released applications should not enable validation layers by default.

2.7.1. Valid Usage

Valid usage defines a set of conditions which m= ust be met in order to achieve well-defined run-time behavior in an application. These conditions depend only on Vulkan state, and the parameters or objects whose usage is constrained by the condition.

Some valid usage conditions have dependencies on run-time limits or feat= ure availability. It is possible to validate these conditions against Vulkan=E2=80=99s minimu= m supported values for these limits and features, or some subset of other known values.

Valid usage conditions do not cover conditions where well-defined behavi= or (including returning an error code) exists.

Valid usage conditions should apply to= the command or structure where complete information about the condition would be known during execution of an application. This is such that a validation layer or linter can= be written directly against these statements at the point they are specified.

Note

This does lead to some non-obvious places for valid usage statements. For instance, the valid values for a structure might depend on a separate value in the calling command. In this case, the structure itself will not reference this valid usage as i= t is impossible to determine validity from the structure that it is invalid - instead this valid usage would be attached to the calling command.

Another example is draw state - the state setters are independent, and c= an cause a legitimately invalid state configuration between draw calls; so the valid usage statements are attached to the place where all state needs to b= e valid - at the draw command.

Valid usage conditions are described in a block labelled =E2=80=9CValid = Usage=E2=80=9D following each command or structure they apply to.

2.7.2. Implicit Valid Usage

Some valid usage conditions apply to all commands and structures in the = API, unless explicitly denoted otherwise for a specific command or structure. These conditions are considered implicit, and are described in a b= lock labelled =E2=80=9CValid Usage (Implicit)=E2=80=9D following each command or= structure they apply to. Implicit valid usage conditions are described in detail below.

Valid Usage for Object Handles

Any input parameter to a command that is an object handle must be a valid object handle, unless otherwise specified. An object handle is valid if:

  • It has been created or allocated by a previous, successful call to the API. Such calls are noted in the Specification.

  • It has not been deleted or freed by a previous call to the API. Such calls are noted in the Specification.

  • Any objects used by that object, either as part of creation or execution, must also be valid.

The reserved values VK_NULL_HANDLE and NULL can be used in place of valid non-dispatchable handles and dispatchable handles, respectively, when explicitly called out in the Specification. Any command that creates an object successfully mu= st not return these values. It is valid to pass these values to vkDestroy* or vkFree= * commands, which will silently ignore these values.

Valid Usage for Pointers

Any parameter that is a pointer must b= e a valid pointer only if it is explicitly called out by a Valid Usage statement.

A pointer is =E2=80=9Cvalid=E2=80=9D if it points at memory containing v= alues of the number and type(s) expected by the command, and all fundamental types accessed through the pointer (e.g. as elements of an array or as members of a structure) satisfy the alignment requirements of the host processor.

Valid Usage for Strings

Any parameter that is a pointer to char must be a finite sequence of values terminated by a null character, or if explicitly called out in t= he Specification, can be NULL.

Valid Usage for Enumerated Types

Any parameter of an enumerated type must be a valid enumerant for that type. A enumerant is valid if:

  • The enumerant is defined as part of the enumerated type.

  • The enumerant is not one of the special values defined for the enumerated type, which are suffixed with _BEGIN_RANGE, _END_RANGE, _RANGE_SIZE or _MAX_ENUM= 1.

    1

    The meaning of these special tokens is not exposed in the Vulkan Specification. They are not part of the API, and they should not be used by applications. Their original intended use was for internal consumption by Vulkan implementations. Even that use will no longer be supported in the future, but they will be retained for backwards compatibility reasons.

Any enumerated type returned from a query command or otherwise output fr= om Vulkan to the application must not have a= reserved value. Reserved values are values not defined by any extension for that enumerated type.

Note

This language is intended to accomodate cases such as =E2=80=9Chidden=E2= =80=9D extensions known only to driver internals, or layers enabling extensions without knowledge of the application, without allowing return of values not defined by any extension.

Valid Usage for Flags

A collection of flags is represented by a bitmask using the type VkFlags:

typedef uint32_t VkFlags;

Bitmasks are passed to many commands and structures to compactly represe= nt options, but VkFlags is not used directly in the API. Instead, a Vk*Flags type which is an alias of VkFlags, and whose name matches the corresponding Vk*FlagBits that are vali= d for that type, is used.

Any Vk*Flags member or parameter used in the API as an inpu= t must be a valid combination of bit flags. A valid combination is either zero or the bitwise OR of valid bit flags. A bit flag is valid if:

  • The bit flag is defined as part of the Vk*FlagBits type, wh= ere the bits type is obtained by taking the flag type and replacing the trailing Flags with FlagBits. For example, a flag value of type VkColorComponentFl= ags must contain only bit flags defined by VkColorComponen= tFlagBits.

  • The flag is allowed in the context in which it is being used. For example, in some cases, certain bit flags or combinations of bit flags are mutually exclusive.

Any Vk*Flags member or parameter returned from a query comm= and or otherwise output from Vulkan to the application ma= y contain bit flags undefined in its corresponding Vk*FlagBits type. An application cannot rely on the state o= f these unspecified bits.

Valid Usage for Structure Types

Any parameter that is a structure containing a sType member= must have a value of sType which is a valid VkStructure= Type value matching the type of the structure.

Structure types supported by the Vulkan API include:

typedef enum VkStructureType {
    VK_STRUCTURE_TYPE_APPLICATION_INFO =3D 0=
,
    VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO =3D 1,
    VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO =3D =
2,
    VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO =3D 3,
    VK_STRUCTURE_TYPE_SUBMIT_INFO =3D 4,
    VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO =3D 5,
    VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE =3D 6,
    VK_STRUCTURE_TYPE_BIND_SPARSE_INFO =3D 7=
,
    VK_STRUCTURE_TYPE_FENCE_CREATE_INFO =3D 8,
    VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO =3D 9,
    VK_STRUCTURE_TYPE_EVENT_CREATE_INFO =3D 10,
    VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO =3D 11=
,
    VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO =3D 12,
    VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO =3D 1=
3,
    VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO =3D 14,
    VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO =3D 15=
,
    VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO =3D 16,
    VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO =3D 17,
    VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO =3D 18,
    VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO =3D 19,
    VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO =3D 20,
    VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO =3D 21,
    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO =3D 22,
    VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO =3D 23,
    VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO =3D 24,
    VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO =3D 25,
    VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO =3D 26,
    VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO =3D 27,
    VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO =3D 28,
    VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO =3D 29,
    VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO =3D 30,
    VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO =3D 31,
    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO =3D 32,
    VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO =3D 33,
    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO =3D 34,
    VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET =3D 35,
    VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET =3D 36,
    VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO =3D 3=
7,
    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO =3D 3=
8,
    VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO =3D =
39,
    VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO =3D 40,
    VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO =3D 41,
    VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO =3D 42,
    VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO =3D 43=
,
    VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER =3D 44<=
/span>,
    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER =3D 45,
    VK_STRUCTURE_TYPE_MEMORY_BARRIER =3D 46,
    VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO =3D 47,
    VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO =3D 48,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES =3D 1000094000,
    VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO =3D 1=
000157000,
    VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO =3D 10=
00157001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES =3D 1000083000,
    VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS =3D 1000127000,
    VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO =3D 1000127001,
    VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO =3D 1000060000,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO =3D 1000060003,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO =3D 1000060004,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO =3D =
1000060005,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO =3D 1000060006,
    VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO =3D 1000060013,
    VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO =3D 1000060014,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES =3D 1000070000,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO =3D 1000070001,
    VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 =3D 1000146000,
    VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 =3D 1000146001,
    VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 =3D 1000146002,
    VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 =3D 100=
0146003,
    VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 =3D 1000146004,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 =3D 1000059000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 =3D 1000059001,
    VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 =3D 10000=
59002,
    VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 =3D 1000059003,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 =3D 1000059004,
    VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 =3D 1000059005,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 =3D 1000059006,
    VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 =3D 1000059007,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 =3D 1000059008,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES =3D 1000117000,
    VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO =3D <=
span class=3D"integer">1000117001,
    VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO =3D 1000117002,
    VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO=
 =3D 1000117003,
    VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO =3D 1000053000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES =3D 1000053001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES =3D 1000053002,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES =3D 1000120000,
    VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO =3D 100=
0145000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES =3D 1000145001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES =3D 1000145002,
    VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 =3D 10001=
45003,
    VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO =3D 1000156000,
    VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO =3D 1000156001,
    VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO =3D 1000156002,
    VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO =3D 1000156003,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES =3D=
 1000156004,
    VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES =3D =
1000156005,
    VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO =3D 1000085000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO =3D 1000071000,
    VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES =3D 1000071001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO =3D 1000071002,
    VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES =3D 1000071003,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES =3D 1000071004,
    VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO =3D 1000072000,
    VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO =3D 1000072001,
    VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO =3D 1000072002,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO =3D 1000112000,
    VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES =3D 1000112001,
    VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO =3D =
1000113000,
    VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO =3D 1000077000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO =3D 1000076000,
    VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES =3D 1000076001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES =3D 1000168000,
    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT =3D 1000168001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES =3D 1000063000,
    VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR =3D 1000001000,
    VK_STRUCTURE_TYPE_PRESENT_INFO_KHR =3D 10000010=
01,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR =3D 1000060007,
    VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR =3D 1000060008,
    VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR =3D 1000060009,
    VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR =3D 1000060010,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR =3D 1000060011,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR =3D 1000060012,
    VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR =3D 1000002000,
    VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR =3D 1000002001,
    VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR =3D =
1000003000,
    VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR =3D 1000004000,
    VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR =3D 1000005000,
    VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR =3D 1000006000,
    VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR =3D 1000007000,
    VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR =3D 1000008000,
    VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR =3D 1000009000,
    VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT =3D 1000011000,
    VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD =
=3D 1000018000,
    VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT =3D 1000022000,
    VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT =3D 1000022001,
    VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT =3D 1000022002,
    VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV =3D 1000026000,
    VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV =3D 1000026001,
    VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV =3D 1000026002,
    VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD =3D 1000041000,
    VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV =3D 1000056000,
    VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV =3D 1000056001,
    VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV =3D 1000057000,
    VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV =3D 1000057001,
    VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV =3D 1000058000,
    VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT =3D 1000=
061000,
    VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN =3D 1000062000,
    VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR =3D 1000073000,
    VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR =3D 1000073001,
    VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR =3D 1000073002,
    VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR =3D 1000073003,
    VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR =3D 1000074000,
    VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR =3D =
1000074001,
    VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR =3D 10=
00074002,
    VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR =3D 1000075000,
    VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR =3D 1000078000,
    VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR =3D 1000078001,
    VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR =3D 1000078002,
    VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR =3D 1000078003,
    VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR =3D 1000079000,
    VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR =3D 1000079001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR =3D 1000080000,
    VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO=
_EXT =3D 1000081000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT =
=3D 1000081001,
    VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT =3D 1000081002,
    VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR =3D 10000=
84000,
    VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX =3D 1000086000,
    VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX =3D 1000086001,
    VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX =3D 1000086002,
    VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX =3D 1000086003,
    VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX =3D 1000086004,
    VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX =3D 1000086005,
    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV =3D =
1000087000,
    VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT =3D 1000090000,
    VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT =3D 10=
00091000,
    VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT =3D 100=
0091001,
    VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT =3D 10=
00091002,
    VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT =3D 1000091003,
    VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE =3D 1000092000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERT=
IES_NVX =3D 1000097000,
    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV =3D 1000098000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT =3D =
1000099000,
    VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT =3D =
1000099001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES=
_EXT =3D 1000101000,
    VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO=
_EXT =3D 1000101001,
    VK_STRUCTURE_TYPE_HDR_METADATA_EXT =3D 10001050=
00,
    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR =3D 1000109000,
    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR =3D 1000109001,
    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR =3D 1000109002,
    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR =3D =
1000109003,
    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR =3D 1000109004,
    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR =3D 10=
00109005,
    VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR =3D 1000=
109006,
    VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR =3D 1000111000,
    VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR =3D 1000114000,
    VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR =3D 1000114001,
    VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR =3D 1000114002,
    VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR =3D =
1000115000,
    VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR =3D 100=
0115001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR =3D 1000119000,
    VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR =3D 1000119001,
    VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR =3D 1000=
119002,
    VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR =3D =
1000121000,
    VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR =3D 1000121001,
    VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR =3D 1000121002,
    VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR =3D =
1000121003,
    VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR =3D 1000121004,
    VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK =3D 1000122000,
    VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK =3D 1000123000,
    VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT =3D 1000128000,
    VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT =3D 1000128001,
    VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT =3D 100=
0128002,
    VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT =3D 1000128003,
    VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT =3D 1000128004,
    VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID =3D 1000129000,
    VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID =3D 1000129001,
    VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID =3D=
 1000129002,
    VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID =3D 1000129003,
    VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID =3D <=
span class=3D"integer">1000129004,
    VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID =3D 1=
000129005,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT =
=3D 1000130000,
    VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT =3D 1000130001,
    VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT =3D 1000143000,
    VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT =3D 1000143001,
    VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT =3D <=
span class=3D"integer">1000143002,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT =3D <=
span class=3D"integer">1000143003,
    VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT =3D 1000143004,
    VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR =3D 1000147000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT=
 =3D 1000148000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_E=
XT =3D 1000148001,
    VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT =
=3D 1000148002,
    VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV =3D <=
span class=3D"integer">1000149000,
    VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV =3D=
 1000152000,
    VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT =3D 1000160000,
    VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT =3D 1000160001,
    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT =
=3D 1000161000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT =3D =
1000161001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT =
=3D 1000161002,
    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INF=
O_EXT =3D 1000161003,
    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPO=
RT_EXT =3D 1000161004,
    VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT =3D 1000174000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR =3D 1000177000,
    VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT =3D 1000178000,
    VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT =3D 1000178001,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT =
=3D 1000178002,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD =3D 1000185000,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_E=
XT =3D 1000190000,
    VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT =
=3D 1000190001,
    VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV =3D 100020=
6000,
    VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV =3D 1000206001,
    VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR =3D VK_STRUCTUR=
E_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR =3D VK_STRUCTU=
RE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR =3D VK_STRUC=
TURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR =3D VK_STRUCTURE_TYPE_=
PHYSICAL_DEVICE_FEATURES_2,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR =3D VK_STRUCTURE_TYP=
E_PHYSICAL_DEVICE_PROPERTIES_2,
    VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR =3D VK_STRUCTURE_TYPE_FORMAT_=
PROPERTIES_2,
    VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR =3D VK_STRUCTURE_TYPE_I=
MAGE_FORMAT_PROPERTIES_2,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR =3D VK_STRUCT=
URE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
    VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR =3D VK_STRUCTURE_TYPE_Q=
UEUE_FAMILY_PROPERTIES_2,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR =3D VK_STRUCT=
URE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
    VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR =3D VK_STRUCTURE=
_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR =3D VK=
_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
    VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR =3D VK_STRUCTURE_TYPE_=
MEMORY_ALLOCATE_FLAGS_INFO,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR =3D VK_STRUCT=
URE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR =3D VK_STR=
UCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR =3D VK_STRUCTURE_TYPE_DE=
VICE_GROUP_SUBMIT_INFO,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR =3D VK_STRUCTURE_TY=
PE_DEVICE_GROUP_BIND_SPARSE_INFO,
    VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR =3D VK_STRUC=
TURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO,
    VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR =3D VK_STRUCT=
URE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR =3D VK_STRUCTURE=
_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES,
    VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR =3D VK_STRUCTURE_=
TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR =3D VK=
_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
    VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR =3D VK_STRUCTURE=
_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR =3D VK_STRUC=
TURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
    VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR =3D VK_STRUCTURE_TYPE_=
EXTERNAL_BUFFER_PROPERTIES,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR =3D VK_STRUCTURE_TY=
PE_PHYSICAL_DEVICE_ID_PROPERTIES,
    VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR =3D VK_STRUCTU=
RE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
    VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR =3D VK_STRUCTUR=
E_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
    VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR =3D VK_STRUCTURE_TYPE=
_EXPORT_MEMORY_ALLOCATE_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR =3D VK_ST=
RUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
    VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR =3D VK_STRUCTURE_TY=
PE_EXTERNAL_SEMAPHORE_PROPERTIES,
    VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR =3D VK_STRUCTURE_TYP=
E_EXPORT_SEMAPHORE_CREATE_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR =3D VK_STR=
UCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
    VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR =3D VK_STR=
UCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR =3D VK_STRUCT=
URE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
    VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR =3D VK_STRUCTURE_TYPE_E=
XTERNAL_FENCE_PROPERTIES,
    VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR =3D VK_STRUCTURE_TYPE_EX=
PORT_FENCE_CREATE_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR =3D VK_=
STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES,
    VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR =
=3D VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
    VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR =3D VK_STRUCTURE_TYP=
E_IMAGE_VIEW_USAGE_CREATE_INFO,
    VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO=
_KHR =3D VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE=
_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR =3D VK_=
STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES,
    VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR =3D VK_STRUCTURE_TY=
PE_MEMORY_DEDICATED_REQUIREMENTS,
    VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR =3D VK_STRUCTURE_T=
YPE_MEMORY_DEDICATED_ALLOCATE_INFO,
    VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR =3D VK_STRUCTUR=
E_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
    VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR =3D VK_STRUCTURE=
_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
    VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR =3D VK_ST=
RUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
    VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR =3D VK_STRUCTURE_TYPE_MEMOR=
Y_REQUIREMENTS_2,
    VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR =3D VK_STRUCTU=
RE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2,
    VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR =3D VK_STRUC=
TURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
    VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR =3D VK_STRUCTURE_TY=
PE_SAMPLER_YCBCR_CONVERSION_INFO,
    VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR =3D VK_STRUCTURE_TYP=
E_BIND_IMAGE_PLANE_MEMORY_INFO,
    VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR =3D VK_STRUC=
TURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR=
 =3D VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
    VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR =
=3D VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
    VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR =3D VK_STRUCTURE_TYPE_BIN=
D_BUFFER_MEMORY_INFO,
    VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR =3D VK_STRUCTURE_TYPE_BIND=
_IMAGE_MEMORY_INFO,
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR =3D VK_S=
TRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR =3D VK_STRUCTURE_TY=
PE_DESCRIPTOR_SET_LAYOUT_SUPPORT,
} VkStructureType;

Each value corresponds to a particular structure with a sType member with a matching name. As a general rule, the name of each VkStructureType value is o= btained by taking the name of the structure, stripping the leading Vk, prefixing each capital letter with _, converting the entire re= sulting string to upper case, and prefixing it with VK_STRUCTURE_TYPE_= . For example, structures of type VkImageCreateInfo correspond t= o a VkStructureType of VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, and thus its sType member must equal = that when it is passed to the API.

The values VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO an= d VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO are reserved for i= nternal use by the loader, and do not have corresponding Vulkan structures in this Specification.

Valid Usage for Structure Pointer = Chains

Any parameter that is a structure containing a void* = pNext member must have a value of pNext t= hat is either NULL, or points to a valid structure defined by an extension, containing sType and pNext members as described in the Vulkan Documentation and Extensions document in the section =E2=80=9CExtension Interactions=E2=80=9D. The set of structures connected by pNext pointers is referred = to as a pNext chain. If that extension is supported by the implementation, then it must be enabled.

Each type of valid structure must not = appear more than once in a pNext chain.

Any component of the implementation (the loader, any enabled layers, and drivers) must skip over, without processi= ng (other than reading the sType and pNext members) any structures in the ch= ain with sType values not defined by extensions supported by that compo= nent.

Extension structures are not described in the base Vulkan Specification,= but either in layered Specifications incorporating those extensions, or in separate vendor-provided documents.

As a convenience to implementations and layers needing to iterate throug= h a structure pointer chain, the Vulkan API provides the following base structures:

typedef struct VkBaseInStructur=
e {
    VkStructureType                    sType;
    const struct VkBaseInStructure*    pNext;
} VkBaseInStructure;
typedef struct VkBaseOutStructu=
re {
    VkStructureType               sType;
    struct VkBaseOutStructure*    pNext;
} VkBaseOutStructure;

VkBaseInStructure can be used to facilitate iterating throu= gh a read-only structure pointer chain. VkBaseOutStructure can be used to facilitate iterating through= a structure pointer chain that returns data back to the application. These structures allow for some type safety and can be used by Vulkan API functions that operate on generic inputs and outputs.

Valid Usage for Nested St= ructures

The above conditions also apply recursively to members of structures provided as input to a command, either as a direct argument to the command, or themselves a member of another structure.

Specifics on valid usage of each command are covered in their individual sections.

Valid Usage for Extensions

Instance-level functionality or behavior added by an instanc= e extension to the API must not be used= unless that extension is supported by the instance as determined by vkEnumerateInstanceExtensionPropert= ies, and that extension is enabled in VkInstanceCreateInfo.

Physical-device-level functionality or behavior added by an = instance extension to the API must no= t be used unless that extension is supported by the instance as determined by vkEnumerateInstanceExtensionPropert= ies, and that extension is enabled in VkInstanceCreateInfo.

Physical-device-level functionality or behavior added by a d= evice extension to the API must not b= e used unless the conditions described in Extending Physical Device Core Functionality are met.

Device functionality or behavior added by a device extension= to the API must not be used unless that e= xtension is supported by the device as determined by vkEnumerateDe= viceExtensionProperties, and that extension is enabled in VkDeviceCreateInfo.

Valid Usage for Newer Core Vers= ions

Instance-level functionality or behavior added by a new core version of the API must not be used u= nless it is supported by the instance as determined by vkEnumerateInstanceVe= rsion.

Physical-device-level functionality or behavior added by a new core version of the API must not be u= sed unless it is supported by the physical device as determined by vkGetPhysic= alDeviceProperties.

Device-level functionality or behavior added by a new core version of the API must not be used u= nless it is supported by the device as determined by vkGetPhysicalDeviceProperti= es.

2.7.3. Return Codes

While the core Vulkan API is not designed to capture incorrect usage, so= me circumstances still require return codes. Commands in Vulkan return their status via return codes that are in one of two categories:

  • Successful completion codes are returned when a command needs to communicate success or status information. All successful completion codes are non-negative values.

  • Run time error codes are returned when a command needs to communicate a failure that could only be detected at run time. All run time error codes are negative values.

All return codes in Vulkan are reported via VkResult retur= n values. The possible codes are:

typedef enum VkResult {
    VK_SUCCESS =3D 0,
    VK_NOT_READY =3D 1,
    VK_TIMEOUT =3D 2,
    VK_EVENT_SET =3D 3,
    VK_EVENT_RESET =3D 4,
    VK_INCOMPLETE =3D 5,
    VK_ERROR_OUT_OF_HOST_MEMORY =3D -1,
    VK_ERROR_OUT_OF_DEVICE_MEMORY =3D -2,
    VK_ERROR_INITIALIZATION_FAILED =3D -3,
    VK_ERROR_DEVICE_LOST =3D -4,
    VK_ERROR_MEMORY_MAP_FAILED =3D -5,
    VK_ERROR_LAYER_NOT_PRESENT =3D -6,
    VK_ERROR_EXTENSION_NOT_PRESENT =3D -7,
    VK_ERROR_FEATURE_NOT_PRESENT =3D -8,
    VK_ERROR_INCOMPATIBLE_DRIVER =3D -9,
    VK_ERROR_TOO_MANY_OBJECTS =3D -10,
    VK_ERROR_FORMAT_NOT_SUPPORTED =3D -11,
    VK_ERROR_FRAGMENTED_POOL =3D -12,
    VK_ERROR_OUT_OF_POOL_MEMORY =3D -1000069000,
    VK_ERROR_INVALID_EXTERNAL_HANDLE =3D -100007200=
3,
    VK_ERROR_SURFACE_LOST_KHR =3D -1000000000,
    VK_ERROR_NATIVE_WINDOW_IN_USE_KHR =3D -10000000=
01,
    VK_SUBOPTIMAL_KHR =3D 1000001003,
    VK_ERROR_OUT_OF_DATE_KHR =3D -1000001004=
,
    VK_ERROR_INCOMPATIBLE_DISPLAY_KHR =3D -10000030=
01,
    VK_ERROR_VALIDATION_FAILED_EXT =3D -1000011001<=
/span>,
    VK_ERROR_INVALID_SHADER_NV =3D -1000012000,
    VK_ERROR_FRAGMENTATION_EXT =3D -1000161000,
    VK_ERROR_NOT_PERMITTED_EXT =3D -1000174001,
    VK_ERROR_OUT_OF_POOL_MEMORY_KHR =3D VK_ERROR_OUT_OF_POOL_MEMORY,
    VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR =3D VK_ERROR_INVALID_EXTERNAL_HAND=
LE,
} VkResult;
Success Codes
  • VK_SUCCESS Command successfully completed

  • VK_NOT_READY A fence or query has not yet completed

  • VK_TIMEOUT A wait operation has not completed in the specif= ied time

  • VK_EVENT_SET An event is signaled

  • VK_EVENT_RESET An event is unsignaled

  • VK_INCOMPLETE A return array was too small for the result

  • VK_SUBOPTIMAL_KHR A swapchain no longer matches the surface properties exactly, but can still be used= to present to the surface successfully.

Error codes
  • VK_ERROR_OUT_OF_HOST_MEMORY A host memory allocation has fa= iled.

  • VK_ERROR_OUT_OF_DEVICE_MEMORY A device memory allocation ha= s failed.

  • VK_ERROR_INITIALIZATION_FAILED Initialization of an object = could not be completed for implementation-specific reasons.

  • VK_ERROR_DEVICE_LOST The logical or physical device has bee= n lost. See Lost Device

  • VK_ERROR_MEMORY_MAP_FAILED Mapping of a memory object has f= ailed.

  • VK_ERROR_LAYER_NOT_PRESENT A requested layer is not present= or could not be loaded.

  • VK_ERROR_EXTENSION_NOT_PRESENT A requested extension is not supported.

  • VK_ERROR_FEATURE_NOT_PRESENT A requested feature is not sup= ported.

  • VK_ERROR_INCOMPATIBLE_DRIVER The requested version of Vulka= n is not supported by the driver or is otherwise incompatible for implementation-specific reasons.

  • VK_ERROR_TOO_MANY_OBJECTS Too many objects of the type have already been created.

  • VK_ERROR_FORMAT_NOT_SUPPORTED A requested format is not sup= ported on this device.

  • VK_ERROR_FRAGMENTED_POOL A pool allocation has failed due t= o fragmentation of the pool=E2=80=99s memory. This must only be returned if no attempt = to allocate host or device memory was made to accomodate the new allocation. This should be returned in preference to VK_ERROR_OUT_OF_POOL_MEMORY, but only if the implementation is certain that the pool allocation failure was due to fragmentation.

  • VK_ERROR_SURFACE_LOST_KHR A surface is no longer available.=

  • VK_ERROR_NATIVE_WINDOW_IN_USE_KHR The requested window is a= lready in use by Vulkan or another API in a manner which prevents it from being used again.

  • VK_ERROR_OUT_OF_DATE_KHR A surface has changed in such a wa= y that it is no longer compatible with the swapchain, and further presentation requests using the swapchain will fail. Applications must query the new surface p= roperties and recreate their swapchain if they wish to continue presenting to the surface.

  • VK_ERROR_INCOMPATIBLE_DISPLAY_KHR The display used by a swa= pchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an image.

  • VK_ERROR_INVALID_SHADER_NV One or more shaders failed to co= mpile or link. More details are reported back to the application via VK_EXT_debug_report if enabled.

  • VK_ERROR_OUT_OF_POOL_MEMORY A pool memory allocation has fa= iled. This must only be returned if no attempt = to allocate host or device memory was made to accomodate the new allocation. If the failure was definitely due to fragmentation of the pool, VK_ERROR_FRAGMENTED_POOL should be returned instead.

  • VK_ERROR_INVALID_EXTERNAL_HANDLE An external handle is not = a valid handle of the specified type.

  • VK_ERROR_FRAGMENTATION_EXT A descriptor pool creation has f= ailed due to fragmentation.

If a command returns a run time error, unless otherwise specified any ou= tput parameters will have undefined contents, except that if the output paramete= r is a structure with sType and pNext fields, those= fields will be unmodified. Any structures chained from pNext will also have undefined con= tents, except that sType and pNext will be unmodified.

Out of memory errors do not damage any currently existing Vulkan objects= . Objects that have already been successfully created can still be used by the application.

Performance-critical commands generally do not have return codes. If a run time error occurs in such commands, the implementation will defer reporting the error until a specified point. For commands that record into command buffers (vkCmd*) run tim= e errors are reported by vkEndCommandBuffer.

2.8. Numeric Representation and Computatio= n

Implementations normally perform computations in floating-point, and must meet the range and precision requirements defined under =E2=80=9CFloating-P= oint Computation=E2=80=9D below.

These requirements only apply to computations performed in Vulkan operat= ions outside of shader execution, such as texture image specification and sampling, and per-fragment operations. Range and precision requirements during shader execution differ and are specified by the Precision and Operation of SPIR-V Instructions section.

In some cases, the representation and/or precision of operations is implicitly limited by the specified format of vertex or texel data consumed by Vulkan. Specific floating-point formats are described later in this section.

2.8.1. Floating-Point Computation

Most floating-point computation is performed in SPIR-V shader modules. The properties of computation within shaders are constrained as defined by the Precision and Operation of SPIR-V Instructions section.

Some floating-point computation is performed outside of shaders, such as viewport and depth range calculations. For these computations, we do not specify how floating-point numbers are to be represented, or the details of how operations on them are performed, but only place minimal requirements on representation and precision as describe= d in the remainder of this section.

editing-note

(Jon, Bug 14966) This is a rat=E2=80=99s nest of complexity, both in ter= ms of describing/enumerating places such computation may= take place (other than =E2=80=9Cnot shader code=E2=80=9D) and in how implementations may do it. We have consciously deferred the resolution of this issue to post-1.0, and in the meantime, the following language inherited from the OpenGL Specification is inserted as a placeholder. Hopefully it can be tightened up consider= ably.

We require simply that numbers=E2=80=99 floating-point parts contain eno= ugh bits and that their exponent fields are large enough so that individual results of floating-point operations are accurate to about 1 part in 105= . The maximum representable magnitude for all floating-point values must be at least 232.

x =C3=97 0 =3D 0 =C3=97 x =3D 0 for any non-in= finite and non-NaN x.

1 =C3=97 x =3D x =C3=97 1 =3D x.

x + 0 =3D 0 + x =3D x.

00 =3D 1.

Occasionally, further requirements will be specified. Most single-precision floating-point formats meet these requirements.

The special values Inf and = -Inf encode values with magnitudes too large to be represented; the special value NaN encodes =E2=80=9CNot A Number=E2=80=9D values resulting from undefined arithmetic operations suc= h as 0 / 0. Implementations may support Inf and NaN in their floating-poin= t computations.

2.8.2. Floating-Point Format Conversi= ons

When a value is converted to a defined floating-point representation, fi= nite values falling between two representable finite values are rounded to one o= r the other. The rounding mode is not defined. Finite values whose magnitude is larger than that of any representable finite value may be rounded either to the closest representable finite valu= e or to the appropriately signed infinity. For unsigned destination formats any negative values are converted to zero. Positive infinity is converted to positive infinity; negative infinity is converted to negative infinity in signed formats and to zero in unsigned formats; and any NaN is converted to a NaN.

2.8.3. 16-Bit Floating-Point Numbers

16-bit floating point numbers are defined in the =E2=80=9C16-bit floatin= g point numbers=E2=80=9D section of the Khronos Data Format Specificat= ion.

2.8.4. Unsigned 11-Bit Floating-Point Numbers<= /h4>

Unsigned 11-bit floating point numbers are defined in the =E2=80=9CUnsig= ned 11-bit floating point numbers=E2=80=9D section of the Khronos Data Fo= rmat Specification.

2.8.5. Unsigned 10-Bit Floating-Point Numbers<= /h4>

Unsigned 10-bit floating point numbers are defined in the =E2=80=9CUnsig= ned 10-bit floating point numbers=E2=80=9D section of the Khronos Data Fo= rmat Specification.

2.8.6. General Requirements

Any representable floating-point value in the appropriate format is lega= l as input to a Vulkan command that requires floating-point data. The result of providing a value that is not a floating-point number to such a command is unspecified, but must not le= ad to Vulkan interruption or termination. For example, providing a negative zero (where applicable) or a denormalized number to an Vulkan command must yield de= terministic results, while providing a NaN or Inf = yields unspecified results.

Some calculations require division. In such cases (including implied divisions performed by vector normalization), division by zero produces an unspecified result but must not lead to Vulkan interruption or termination.

2.9. Fixed-Point Data Conversions

When generic vertex attributes and pixel color or depth components are represented as integers, they are often (but not always) considered to be normalized. Normalized integer values are treated specially when being converted to and from floating-point values, and are usually referred to as normalized fixed-point.

In the remainder of this section, b denotes th= e bit width of the fixed-point integer representation. When the integer is one of the types defined by the API, b is the bit width of that type. When the integer comes from an image containing color or depth component texels, b is the number of bit= s allocated to that component in its specified image format.

The signed and unsigned fixed-point representations are assumed to be b-bit binary two=E2=80=99s-complement integers an= d binary unsigned integers, respectively.

2.9.1. Conversion from Normalized Fixed= -Point to Floating-Point

Unsigned normalized fixed-point integers represent numbers in the range [0,1]. The conversion from an unsigned normalized fixed-point value c to the corresponding floating-point value f is defined a= s

\[f =3D { c \over { 2^b - 1 } }\]

Signed normalized fixed-point integers represent numbers in the range [-1,1]. The conversion from a signed normalized fixed-point value c to the corresponding floating-point value f is performed= using

\[f =3D \max\left( {c \over {2^{b-1} - 1}}, -1.0 \right)\]

Only the range [-2b-1 + 1, 2b-1 - 1] is used to represent signed fixed-point values in the range [-1,1]. For example, if b =3D 8, then the integer value <= span class=3D"eq">-127 corresponds to -1.0 and the value 127 corresponds to 1.0. Note that while zero is exactly expressible in this representation, one value (-128 in the example) is outside the repres= entable range, and must be clamped before use. This equation is used everywhere that signed normalized fixed-point values are converted to floating-point.

2.9.2. Conversion from Floating-Point t= o Normalized Fixed-Point

The conversion from a floating-point value f t= o the corresponding unsigned normalized fixed-point value c is define= d by first clamping f to the range [0,1], t= hen computing

c =3D convertFloatToUint(f =C3=97 (2b - 1)= , b)

where convertFloatToUint}(r,b) returns one of = the two unsigned binary integer values with exactly b bits which are clos= est to the floating-point value r. Implementations should round to nearest. If r is equal to an integer, then that integer va= lue must be returned. In particular, if f is equal to 0.0 or 1.0, then = c must be assigned 0 or 2b - 1, respectively.

The conversion from a floating-point value f t= o the corresponding signed normalized fixed-point value c is performe= d by clamping f to the range [-1,1], then computing

c =3D convertFloatToInt(f =C3=97 (2b-1 - 1= ), b)

where convertFloatToInt(r,b) returns one of th= e two signed two=E2=80=99s-complement binary integer values with exactly b bits which are closest to the floating-point value r. Implementations should round to nearest. If r is equal to an integer, then that integer va= lue must be returned. In particular, if f is equal to -1.0, 0.0, or 1.0= , then c must be assigned -(2b-1 - 1), 0, or 2b-1 - 1, respectively.

This equation is used everywhere that floating-point values are converte= d to signed normalized fixed-point.

2.10. API Version Numbers and Semantics<= /h3>

The Vulkan version number is used in several places in the API. In each such use, the API major version number, minor version = number, and patch version number are packed into a 32-bit integer as follo= ws:

  • The major version number is a 10-bit integer packed into bits 31-22.

  • The minor version number is a 10-bit integer packed into bits 21-12.

  • The patch version number is a 12-bit integer packed into bits 11-0.

Differences in any of the Vulkan version numbers indicates a change to t= he API in some way, with each part of the version number indicating a differen= t scope of changes.

A difference in patch version numbers indicates that some usually small = part of the Specification or header has been modified, typically to fix a bug, and may have an impact on the behavior of= existing functionality. Differences in this version number should= not affect either full compatibility or backwards compatibility between two versions= , or add additional interfaces to the API.

A difference in minor version numbers indicates that some amount of new functionality has been added. This will usually include new interfaces in the header, and may also include behavior changes and bug fixes. Functionality may be deprecated in a mino= r revision, but will not be removed. The patch version will continue to increment through minor version number changes since all minor versions are generated from the same source files, and changes to the source files may affect all minor versions within a majo= r version. Differences in the patch version should n= ot affect backwards compatibility, but will affect full compatibility. The patch version of the Specification is taken from VK_HEADER_VERSION.

A difference in major version numbers indicates a large set of changes t= o the API, potentially including new functionality and header interfaces, behavioral changes, removal of deprecated features, modification or outrigh= t replacement of any feature, and is thus very likely to break any and all compatibility. Differences in this version will typically require significant modification to an application in order for it to function.

C language macros for manipulating version numbers are defined in the Version Number Macros appendix.

2.11. Common Object Types

Some types of Vulkan objects are used in many different structures and command parameters, and are described here. These types include offsets, extents, and rectangles<= /em>.

2.11.1. Offsets

Offsets are used to describe a pixel location within an image or framebuffer, as an (x,y) location for two-dimensional images, or an (x,y,z) location for three-dimensional images.

A two-dimensional offsets is defined by the structure:

typedef struct VkOffset2D {
    int32_t    x;
    int32_t    y;
} VkOffset2D;
  • x is the x offset.

  • y is the y offset.

A three-dimensional offset is defined by the structure:

typedef struct VkOffset3D {
    int32_t    x;
    int32_t    y;
    int32_t    z;
} VkOffset3D;
  • x is the x offset.

  • y is the y offset.

  • z is the z offset.

2.11.2. Extents

Extents are used to describe the size of a rectangular region of pixels within an image or framebuffer, as (width,height) for two-dimensional images, or as (width,height,depth) for three-dimensional images.

A two-dimensional extent is defined by the structure:

typedef struct VkExtent2D {
    uint32_t    width;
    uint32_t    height;
} VkExtent2D;
  • width is the width of the extent.

  • height is the height of the extent.

A three-dimensional extent is defined by the structure:

typedef struct VkExtent3D {
    uint32_t    width;
    uint32_t    height;
    uint32_t    depth;
} VkExtent3D;
  • width is the width of the extent.

  • height is the height of the extent.

  • depth is the depth of the extent.

2.11.3. Rectangles

Rectangles are used to describe a specified rectangular region of pixels within an image or framebuffer. Rectangles include both an offset and an extent of the same dimensionality, as described above. Two-dimensional rectangles are defined by the structure

typedef struct VkRect2D {
    VkOffset2D    offset;
    VkExtent2D    extent;
} VkRect2D;
  • offset is a VkOffset2D specifying the recta= ngle offset.

  • extent is a VkExtent2D specifying the recta= ngle extent.

3. Initialization

Before using Vulkan, an application must initialize it by loading the Vulkan commands, and creating a VkInstance object.

3.1. Command Function Pointers

Vulkan commands are not necessarily exposed statically on a platform. Function pointers for all Vulkan commands can be obtained with the command:

PFN_vkVoidFunction=
 vkGetInstanceProcAddr(
    VkInstance                                  instance,
    const =
char*                                 pName);
  • instance is the instance that the function pointer will be compatible with, or NULL for commands not dependent on any ins= tance.

  • pName is the name of the command to obtain.

vkGetInstanceProcAddr itself is obtained in a platform- and= loader- specific manner. Typically, the loader library will export this command as a function symbol= , so applications can link against the load= er library, or load it dynamically and look up the symbol using platform-specific APIs.

The table below defines the various use cases for vkGetInstanceProcAddr and expected return value (=E2=80=9Cfp= =E2=80=9D is =E2=80=9Cfunction pointer=E2=80=9D) for each case.

The returned function pointer is of type PFN_vkVoidF= unction, and must be cast to the type of the command being queried.

Table 1. vkGetInstanceProcAddr behavior
instance pName return value

*

NULL

und= efined

inv= alid instance

*

und= efined

NULL

vkEnumerateInstanceVersion

fp<= /p>

NULL

vkEnumerateInstanceExtensionProperties=

fp<= /p>

NULL

vkEnumerateInstanceLayerProperties

=

fp<= /p>

NULL

vkCreateInstance

fp<= /p>

NULL

* (= any pName not covered above)

NULL

ins= tance

cor= e Vulkan command

fp<= sup>1

ins= tance

ena= bled instance extension commands for instance

fp<= sup>1

ins= tance

ava= ilable device extension2 commands for instance

<= /td>

fp<= sup>1

ins= tance

* (= any pName not covered above)

NULL

1

The returned function pointer must onl= y be called with a dispatchable object (the first parameter) that is instance or a child of instance, e.g. VkInstance, V= kPhysicalDevice, VkDevice, VkQueue, or VkCommand= Buffer.

2

An =E2=80=9Cavailable device extension=E2=80=9D is a device extension su= pported by any physical device enumerated by instance.

Valid Usage (Implicit)
  • If in= stance is not NULL, instance must be a valid VkInstance handle

  • pName must be a null-terminated UTF-8 stri= ng

In order to support systems with multiple Vulkan implementations, the function pointers returned by vkGetInstanceProcAddr may point to dispatch code that calls a different real implementation for different VkDevice objects or their child objects. The overhead of the internal dispatch for VkDevice objects ca= n be avoided by obtaining device-specific function pointers for any commands tha= t use a device or device-child object as their dispatchable object. Such function pointers can be obtained wi= th the command:

PFN_vkVoidFunction=
 vkGetDeviceProcAddr(
    VkDevice                                    device,
    const =
char*                                 pName);

The table below defines the various use cases for vkGetDeviceProcA= ddr and expected return value for each case.

The returned function pointer is of type PFN_vkVoidF= unction, and must be cast to the type of the command being queried. The function pointer must only be called = with a dispatchable object (the first parameter) that is device or a child of device.

Table 2. vkGetDeviceProcAddr behavior
device pName return value

NULL

*

und= efined

inv= alid device

*

und= efined

dev= ice

NULL

und= efined

dev= ice

cor= e device-level Vulkan command

fp<= /p>

dev= ice

ena= bled device extension commands

fp<= /p>

dev= ice

* (= any pName not covered above)

NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pName must be a null-terminated UTF-8 string=

The definition of PFN_vkVoidFunction is:

typedef void (VKAPI_PTR *PFN_=
vkVoidFunction)(void);

3.1.1. Extending P= hysical Device Core Functionality

New core physical-device-level functionality ca= n be used when the physical-device version is greater than or equal to the version of Vulkan that added the new functionality. The Vulkan version supported by a physical device = can be obtained by calling vkGetPhysicalDeviceProperties.

3.1.2. Extending Physical Dev= ice From Device Extensions

When the VK_KHR_get_physic= al_device_properties2 extension is enabled, or when both the instance and the physical-device versions are at least 1.1= , physical-device-level functionality of a device extension can be used with a physical device if the corresponding extension is enumerated by vkEnumerateDeviceExtensionProperties<= /a> for that physical device, even before a logical device has been created.

To obtain a function pointer for a physical-device-level command from a device extension, an application can use = vkGetInstanceProcAddr. This function pointer may point to dispat= ch code, which calls a different real implementation for different VkPhysicalDevice objects. Behavior is undefined if an extension physical-device command is called on = a physical device that does not support the extension.

Device extensions may define structure= s that can be added to the pNext chain of physical-device-level commands. Behavior is undefined if such an extension structure is passed to a physical-device-level command for a physical device that does not support the extension.

3.2. Instances

There is no global state in Vulkan and all per-application state is stor= ed in a VkInstance object. Creating a VkInstance object initializes the Vulkan library an= d allows the application to pass information about itself to the implementation.

Instances are represented by VkInstance handles:

VK_DEFINE_HANDLE(V=
kInstance)

The version of Vulkan that is supported by an instance may be different than the version of Vulkan supported by a device or physical device. To query properties that can be used in c= reating an instance, call:

VkResult vkEnumera=
teInstanceVersion(
    uint32_t*                                   pApiVersion);
  • pApiVersion points to a uint32_t, which is the= version of Vulkan supported by instance-level functionality, encoded as described in the API Version Numbers and Semantics section.

Valid Usage (Implicit)
  • pApiVersion must be a valid poi= nter to a uint32_t value

Return Codes
Success
  • VK_SUCCESS

To create an instance object, call:

VkResult vkCreateI=
nstance(
    const VkInstanceCreateInfo*           =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkInstance*                                 pInstance);
  • pCreateInfo points to an instance of = VkInstanceCreateInfo controlling creation of the instance.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pInstance points a VkInstance handle in whi= ch the resulting instance is returned.

vkCreateInstance verifies that the requested layers exist. If not, vkCreateInstance will return VK_ERROR_LAYER_NOT_= PRESENT. Next vkCreateInstance verifies that the requested extensions a= re supported (e.g. in the implementation or in any enabled instance layer) and if any requested extension is not supported, vkCreateInstance = must return VK_ERROR_EXTENSION_NOT_PRESENT. After verifying and enabling the instance layers and extensions the VkInstance object is created and returned to the application. If a requested extension is only supported by a layer, both the layer and the extension need to be specified at vkCreateInstance time fo= r the creation to succeed.

Valid Usage
Valid Usage (Implicit)
  • pCreate= Info must be a valid pointer to a = valid VkInstanceCreateInfo structure

  • If pAllo= cator is not NULL, pAllocator must be a valid pointer to a valid VkAllocation= Callbacks structure

  • pInstance= must be a valid pointer to a VkInstance handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INITIALIZATION_FAILED

  • VK_ERROR_LAYER_NOT_PRESENT

  • VK_ERROR_EXTENSION_NOT_PRESENT

  • VK_ERROR_INCOMPATIBLE_DRIVER

The VkInstanceCreateInfo structure is defined as:

typedef struct VkInstanceCreate=
Info {
    VkStructureType             sType;
    const void*                 pNext;
    VkInstanceCreateFlags       flags;
    const VkApplicationInfo*    pApplicati=
onInfo;
    uint32_t                    enabledLayerCount;
    const =
char* const*          ppEnabledLaye=
rNames;
    uint32_t                    enabledExtensionCount;
    const =
char* const*          ppEnabledExte=
nsionNames;
} VkInstanceCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • pApplicationInfo is NULL or a pointer to an in= stance of VkApplicationInfo. If not NULL, this information helps implementations recognize = behavior inherent to classes of applications. VkApplicationInfo is defined in detail below.

  • enabledLayerCount is the number of global layers to enable.=

  • ppEnabledLayerNames is a pointer to an array of enabledLayerCount null-terminated UTF-8 strings containing the names of layers to enable for the created instance. See the Layers section for further details.

  • enabledExtensionCount is the number of global extensions to enable.

  • ppEnabledExtensionNames is a pointer to an array of enabledExtensionCount null-terminated UTF-8 strings containing= the names of extensions to enable.

Valid Usage (Implicit)
typedef VkFlags VkInstanceCreateFlags;

VkInstanceCreateFlags is a bitmask type for setting a mask,= but is currently reserved for future use.

When creating a Vulkan instance for which you wish to disable validation checks, add a VkValidationFlagsEXT structure to t= he pNext chain of the VkInstanceCreateInfo structure, specifying= the checks to be disabled.

typedef struct VkValidationFlag=
sEXT {
    VkStructureType                sType;
    const void*                    pNext;
    uint32_t                       disabledValidationCheckCount;
    const VkValidationCheckEXT*    pDisabl=
edValidationChecks;
} VkValidationFlagsEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • disabledValidationCheckCount is the number of checks to dis= able.

  • pDisabledValidationChecks is a pointer to an array of VkValidationCheckEXT values specifying the valida= tion checks to be disabled.

Valid Usage (Implicit)
  • sType = must be VK_STRUCTURE_TYPE_VALIDATIO= N_FLAGS_EXT

  • = pDisabledValidationChecks must be a valid pointer to an array of disabledValidationCheckCoun= t valid VkValidationCheckEXT values

  • disabledValidationCheckCount must be greater than 0

Possible values of elements of the VkValidationFlagsEXT::pDisabledValidationCh= ecks array, specifying validation checks to be disabled, are:

typedef enum VkValidationCheckE=
XT {
    VK_VALIDATION_CHECK_ALL_EXT =3D 0,
    VK_VALIDATION_CHECK_SHADERS_EXT =3D 1,
} VkValidationCheckEXT;
  • VK_VALIDATION_CHECK_ALL_EXT specifies that all validation c= hecks are disabled.

  • VK_VALIDATION_CHECK_SHADERS_EXT specifies that shader valid= ation is disabled.

The VkApplicationInfo structure is defined as:

typedef struct VkApplicationInf=
o {
    VkStructureType    sType;
    const void*        pNext;
    const =
char*        pApplicationName;
    uint32_t           applicationVersion;
    const =
char*        pEngineName;
    uint32_t           engineVersion;
    uint32_t           apiVersion;
} VkApplicationInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • pApplicationName is NULL or is a pointer to a = null-terminated UTF-8 string containing the name of the application.

  • applicationVersion is an unsigned integer variable containi= ng the developer-supplied version number of the application.

  • pEngineName is NULL or is a pointer to a null-= terminated UTF-8 string containing the name of the engine (if any) used to create the application.

  • engineVersion is an unsigned integer variable containing th= e developer-supplied version number of the engine used to create the application.

  • apiVersion must be the hi= ghest version of Vulkan that the application is designed to use, encoded as described in the API Version Numbers and Semantics section. The patch version number specified in apiVersion is ignored wh= en creating an instance object. Only the major and minor versions of the instance = must match those requested in apiVersion.

Vulkan 1.0 implementations were required to return VK_ERROR_INCOMPATIBLE_DRIVER if apiVersion was la= rger than 1.0. Implementations that support Vulkan 1.1 or later m= ust not return VK_ERROR_INCOMPATIBLE_DRIVER for any value of apiVersion= .

Note

Because Vulkan 1.0 implementations may= fail with VK_ERROR_INCOMPATIBLE_DRIVER, applications should determine the version of Vulkan available before calling vkCreateInstan= ce. If the vkGetInstanceProcAddr returns NULL<= /code> for vkEnumerateInstanceVersion, it is a Vulkan = 1.0 implementation. Otherwise, the application can call vkEnumerateInstanceVersion to determine the version of Vulkan.

Implicit layers must be disabled if th= ey do not support a version at least as high as apiVersion. See the "Vulkan Loader Specification and Architecture Overview" document for additional information.

Note

Providing a NULL VkInstanceCreateInfo::p= ApplicationInfo or providing an apiVersion of 0 is equivalent to providing an apiVersion of VK_MAKE_VERSION(1,0,0).

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_APPLICATION_= INFO

  • pNext must be NULL

  • If pApplicationName is not NULL, pApplicationName<= /code> must be a null-terminated UTF-8 st= ring

  • If pEn= gineName is not NULL, pEngineName must be a null-terminated UTF-8 string

To destroy an instance, call:

void vkDestroyInstance(
    VkInstance                                  instance,
    const VkAllocationCallbacks*          =
      pAllocator);
  • instance is the handle of the instance to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All child objects created using instance must have been destroyed prior to destroying instance

  • If VkAllocationCallbacks were provided when instance was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when instance<= /code> was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • If instan= ce is not NULL, instance must be a valid VkInstance handle

  • If pAll= ocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocatio= nCallbacks structure

Host Synchronization
  • Host access to instance must be externally synchronized

5. Command Buffers

Command buffers are objects used to record commands which can be subsequently submitted to a device queue for execution. There are two levels of command buffers - primary command buffers,= which can execute secondary command buffers, an= d which are submitted to queues, and secondary command buffers, which can<= /strong> be executed by primary command buffers, and which are not directly submitted to queues.

Command buffers are represented by VkCommandBuffer handles:=

VK_DEFINE_HANDLE(V=
kCommandBuffer)

Recorded commands include commands to bind pipelines and descriptor sets= to the command buffer, commands to modify dynamic state, commands to draw (for graphics rendering), commands to dispatch (for compute), commands to execut= e secondary command buffers (for primary command buffers only), commands to copy buffers and images, and other commands.

Each command buffer manages state independently of other command buffers= . There is no inheritance of state across primary and secondary command buffers, or between secondary command buffers. When a command buffer begins recording, all state in that command buffer is undefined. When secondary command buffer(s) are recorded to execute on a primary command buffer, the secondary command buffer inherits no state from the primary command buffer, and all state of the primary command buffer is undefined after an execute secondary command buffer command is recorded. There is one exception to this rule - if the primary command buffer is inside a render pass instance, then the render pass and subpass state is no= t disturbed by executing secondary command buffers. Whenever the state of a command buffer is undefined, the application must set all relevant state on the command buffer before any state dependent commands such as draws and dispatches are recorded, otherwise the behavior of executing that command buffer is undefined.

Unless otherwise specified, and without explicit synchronization, the various commands submitted to a queue via command buffers may execute in arbitrary order relative to each other, and/or concurrently. Also, the memory side-effects of those commands ma= y not be directly visible to other commands without explicit memory dependencies. This is true within a command buffer, and across command buffers submitted to a given queue. See the synchronization chapter for information on implicit and explicit synchronization between commands.

5.1. Command Buffer Lifecycle

Each command buffer is always in one of the following states:

Initial

When a command buffer is allocated, it is in the initial state. Some commands are able to reset a command buffer, or a set of comm= and buffers, back to this state from any of the executable, recording or invalid state. Command buffers in the initial state can = only be moved to the recording state, or freed.

Recording

vkBeginCommandBuffer changes the state of a co= mmand buffer from the initial state to the recording state. Once a command buffer is in the recording state, vkCmd* comman= ds can be used to record to the command buff= er.

Executable

vkEndCommandBuffer ends the recording of a comma= nd buffer, and moves it from the recording state to the executable state. Executable command buffers can be submitted, reset, or reco= rded to another command buffer.

Pending

Queue submission of a command buffer changes the state of a command buffer from the executable state to the pending state. Whilst in the pending state, applications must not attempt to modify the command buffer in any way - as the device may<= /strong> be processing the commands recorded to it. Once execution of a command buffer completes, the command buffer reverts back to either the executable state, or the invalid state= if it was recorded with VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT. A synchronization command sho= uld be used to detect when this occurs.

Invalid

Some operations, such as m= odifying or deleting a resource that was used in a command recorded to a command buffer, will transition the state of that command buffer into the invalid state. Command buffers in the invalid state can = only be reset or freed.

3D"commandbuffer
Figure 1. Lifecycle of a command buffer

Any given command that operates on a command buffer has its own requirem= ents on what state a command buffer must be in= , which are detailed in the valid usage constraints for that command.

Resetting a command buffer is an operation that discards any previously recorded commands and puts a command buffer in the initial state. Resetting occurs as a result of vkResetCommandBuffer<= /a> or vkResetCommandPool, or as part of vkBeginCommandBuffer (which additionally puts the command buffer in the recording state).

Secondary command buffers can be recorded to a primary command buffer via vkCmdExecuteCommands= . This partially ties the lifecycle of the two command buffers together - if the primary is submitted to a queue, both the primary and any secondaries recorded to it move to the pending state. Once execution of the primary completes, so does any secondary recorded within it, and once all executions of each command buffer complete, they move to the executable state. If a secondary moves to any other state whilst it is recorded to another command buffer, the primary moves to the invalid state. A primary moving to any other state does not affect the state of the secondary. Resetting or freeing a primary command buffer removes the linkage to any secondary command buffers that were recorded to it.

5.2. Command Pools

Command pools are opaque objects that command buffer memory is allocated from, and which allow the implementation to amortize the cost of resource creation across multiple command buffers. Command pools are externally synchronized, meaning that a command pool must not be used concurrently in multiple threads. That includes use via recording commands on any command buffers allocated from the pool, as well as operations that allocate, free, and reset command buffers or the pool itself.

Command pools are represented by VkCommandPool handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkCommandPool)

To create a command pool, call:

VkResult vkCreateC=
ommandPool(
    VkDevice                                    device,
    const VkCommandPoolCreateInfo*        =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkCommandPool*                              pCommandPool);
  • device is the logical device that creates the command pool.=

  • pCreateInfo is a pointer to an instance of the VkCommandPoolCreateInfo structure specifying t= he state of the command pool object.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pCommandPool points to a VkCommandPool h= andle in which the created pool is returned.

Valid Usage
  • pCreateInfo::queueFamilyIndex must be the index of a queue family available in the logical device device.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pCre= ateInfo must be a valid pointer to= a valid VkCommandPoolCreateInfo structure

  • If pA= llocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocat= ionCallbacks structure

  • pCo= mmandPool must be a valid pointer = to a VkCommandPool handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkCommandPoolCreateInfo structure is defined as:

typedef struct VkCommandPoolCre=
ateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkCommandPoolCreateFlags    flags;
    uint32_t                    queueFamilyIndex;
} VkCommandPoolCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkComman= dPoolCreateFlagBits indicating usage behavior for the pool and command buffers allocated from it.

  • queueFamilyIndex designates a queue family as described in = section Queue Family Properties. All command buffers allocated from this command pool must be submitted on queues from the same queue family.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_COMMAN= D_POOL_CREATE_INFO

  • pNext must be NULL

  • flags<= /code> must be a valid combination of VkCommandPoolCreateFlagBits values

Bits which can be set in VkCommandPoolCreateInfo::flags to specify usage behavior for a command pool are:

typedef enum VkCommandPoolCreat=
eFlagBits {
    VK_COMMAND_POOL_CREATE_TRANSIENT_BIT =3D 0x00000001=
,
    VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT =3D 0x00000002,
    VK_COMMAND_POOL_CREATE_PROTECTED_BIT =3D 0x00000004=
,
} VkCommandPoolCreateFlagBits;
  • VK_COMMAND_POOL_CREATE_TRANSIENT_BIT specifies that command buffers allocated from the pool will be short-lived, meaning that they will be reset or freed in a relatively short timeframe. This flag may be used by the implementati= on to control memory allocation behavior within the pool.

  • VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT allows any = command buffer allocated from a pool to be individually reset to the initial state; either by calling vkResetCommandBuffer, or via the implicit reset w= hen calling vkBeginCommandBuffer. If this flag is not set on a pool, then vkResetCommandBuffer <= strong class=3D"purple">must not be called for any command buffer allocated from that pool.

  • VK_COMMAND_POOL_CREATE_PROTECTED_BIT specifies that command buffers allocated from the pool are protected command buffers. If the protected memory feature is not enabled, the VK_COMMAND_POOL_CREATE_PROTECTED_BIT bit of flags= must not be set.

typedef VkFlags VkCommandPoolCreateFlags;

VkCommandPoolCreateFlags is a bitmask type for setting a ma= sk of zero or more VkCommandPoolCreateFlagBits.

To trim a command pool, call:

void vkTrimCommandPool(
    VkDevice                                    device,
    VkCommandPool                               commandPool,
    VkCommandPoolTrimFlags                      flags);

or the equivalent command

void vkTrimCommandPoolKHR(
    VkDevice                                    device,
    VkCommandPool                               commandPool,
    VkCommandPoolTrimFlags                      flags);
  • device is the logical device that owns the command pool.

  • commandPool is the command pool to trim.

  • flags is reserved for future use.

Trimming a command pool recycles unused memory from the command pool bac= k to the system. Command buffers allocated from the pool are not affected by the command.

Note

This command provides applications with some control over the internal memory allocations used by command pools.

Unused memory normally arises from command buffers that have been record= ed and later reset, such that they are no longer using the memory. On reset, a command buffer can return memory to its command pool, but the only way to release memory from a command pool to the system requires calling vkResetCommandPool, which cannot be execute= d while any command buffers from that pool are still in use. Subsequent recording operations into command buffers will re-use this memor= y but since total memory requirements fluctuate over time, unused memory can accumulate.

In this situation, trimming a command pool may<= /strong> be useful to return unused memory back to the system, returning the total outstanding memory allocated by the pool back to a more =E2=80=9Caverage=E2=80=9D value.

Implementations utilize many internal allocation strategies that make it impossible to guarantee that all unused memory is released back to the system. For instance, an implementation of a command pool = may involve allocating memory in bulk from the system and sub-allocating from that memory. In such an implementation any live command buffer that holds a reference to a bulk allocation would prevent that allocation from being freed, even if only a small proportion of the bulk allocation is in use.

In most cases trimming will result in a reduction in allocated but unuse= d memory, but it does not guarantee the =E2=80=9Cideal=E2=80=9D behaviour.

Trimming may be an expensive operation= , and should not be called frequently. Trimming should be treated as a way to re= lieve memory pressure after application-known points when there exists enough unused memory that the cost of trimming is =E2=80=9Cworth=E2=80=9D it.

Valid Usage (Implicit)
  • device must be a valid VkDevice = handle

  • comman= dPool must be a valid VkComm= andPool handle

  • flags must be 0

  • commandPo= ol must have been created, allocat= ed, or retrieved from device

Host Synchronization
  • Host access to commandPool must be externally synchronized

typedef VkFlags VkCommandPoolTrimFlags;

or the equivalent

typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR;

VkCommandPoolTrimFlags is a bitmask type for setting a mask= , but is currently reserved for future use.

To reset a command pool, call:

VkResult vkResetCo=
mmandPool(
    VkDevice                                    device,
    VkCommandPool                               commandPool,
    VkCommandPoolResetFlags                     flags);
  • device is the logical device that owns the command pool.

  • commandPool is the command pool to reset.

  • flags is a bitmask of VkCommand= PoolResetFlagBits controlling the reset operation.

Resetting a command pool recycles all of the resources from all of the command buffers allocated from the command pool back to the command pool. All command buffers that have been allocated from the command pool are put in the initial state.

Any primary command buffer allocated from another VkComma= ndPool that is in the recording or executable state and has a secondary command buffer allocated from commandPool reco= rded into it, becomes invalid.

Valid Usage
  • All VkCommandBuffer objects allocated from commandPool must not be in the pending state

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • comma= ndPool must be a valid VkCom= mandPool handle

  • flags must be a valid combination of VkCommandPoolResetFlagBits values

  • commandP= ool must have been created, alloca= ted, or retrieved from device

Host Synchronization
  • Host access to commandPool must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Bits which can be set in vkResetCommandPool::flags to control the reset operation are:

typedef enum VkCommandPoolReset=
FlagBits {
    VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT =3D 0x0=
0000001,
} VkCommandPoolResetFlagBits;
  • VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT specifies that resetting a command pool recycles all of the resources from the command pool back to the system.

typedef VkFlags VkCommandPoolResetFlags;

VkCommandPoolResetFlags is a bitmask type for setting a mas= k of zero or more VkCommandPoolResetFlagBits.

To destroy a command pool, call:

void vkDestroyCommandPool(
    VkDevice                                    device,
    VkCommandPool                               commandPool,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the command pool= .

  • commandPool is the handle of the command pool to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

When a pool is destroyed, all command buffers allocated from the pool ar= e freed.

Any primary command buffer allocated from another VkComma= ndPool that is in the recording or executable state and has a secondary command buffer allocated from commandPool reco= rded into it, becomes invalid.

Valid Usage
  • All VkCommandBuffer objects allocated from commandPool must not be in the pending state.

  • If VkAllocationCallbacks were provided when commandPool<= /code> was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when commandPo= ol was created, pAllocator must= be NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • If = commandPool is not VK_NULL_HANDLE, command= Pool must be a valid VkComma= ndPool handle

  • If p= Allocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloca= tionCallbacks structure

  • If com= mandPool is a valid handle, it must have been created, allocated, or retrieved from device

Host Synchronization
  • Host access to commandPool must be externally synchronized

5.3. Command Buffer Allocation and Mana= gement

To allocate command buffers, call:

VkResult vkAllocat=
eCommandBuffers(
    VkDevice                                    device,
    const VkCommandBufferAllocateInfo*    =
      pAllocateInfo,
    VkCommandBuffer*                            pCommandBuffers);

vkAllocateCommandBuffers can be used to create multiple command buffers. If the creation of any of those command buffers fails, the implementation must destroy all successfully created com= mand buffer objects from this command, set all entries of the pCommandBuffers array to NULL and return the error.

Valid Usage (Implicit)
  • devi= ce must be a valid VkDevice<= /code> handle

  • pAllocateInfo must be a valid p= ointer to a valid VkCommandBufferAllocateInfo structure

  • <= code>pCommandBuffers must be a val= id pointer to an array of pAllocateInfo::commandBufferCount VkCommandBuffer handles

Host Synchronization
  • Host access to pAllocateInfo::commandPool must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkCommandBufferAllocateInfo structure is defined as:

typedef struct VkCommandBufferA=
llocateInfo {
    VkStructureType         sType;
    const void*             pNext;
    VkCommandPool           commandPool;
    VkCommandBufferLevel    level;
    uint32_t                commandBufferCount;
} VkCommandBufferAllocateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • commandPool is the command pool from which the command buff= ers are allocated.

  • level is an VkCommandBufferLevel = value specifying the command buffer level.

  • commandBufferCount is the number of command buffers to allo= cate from the pool.

Valid Usage
  • commandBufferCount must be g= reater than 0

Valid Usage (Implicit)
  • sType<= /code> must be VK_STRUCTURE_TYPE_CO= MMAND_BUFFER_ALLOCATE_INFO

  • pNext<= /code> must be NULL

  • commandPool must be a valid VkCommandPool handle

  • le= vel must be a valid VkCommandBufferLevel value

Possible values of VkCommandBufferAllocateI= nfo::level, specifying the command buffer level, are:

typedef enum VkCommandBufferLev=
el {
    VK_COMMAND_BUFFER_LEVEL_PRIMARY =3D 0,
    VK_COMMAND_BUFFER_LEVEL_SECONDARY =3D 1,
} VkCommandBufferLevel;
  • VK_COMMAND_BUFFER_LEVEL_PRIMARY specifies a primary command buffer.

  • VK_COMMAND_BUFFER_LEVEL_SECONDARY specifies a secondary com= mand buffer.

To reset command buffers, call:

VkResult vkResetCo=
mmandBuffer(
    VkCommandBuffer                             commandBuffer,
    VkCommandBufferResetFlags                   flags);

Any primary command buffer that is in the reco= rding or executable state and has commandBuffer recorded i= nto it, becomes invalid.

Valid Usage
  • commandBuffer must not be in= the pending state

  • commandBuffer must have been= allocated from a pool that was created with the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT

Valid Usage (Implicit)
Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Bits which can be set in vkResetCommandBuffer::flags to control the reset operation are:

typedef enum VkCommandBufferRes=
etFlagBits {
    VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT =3D 0=
x00000001,
} VkCommandBufferResetFlagBits;
  • VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT specifies tha= t most or all memory resources currently owned by the command buffer should be returned to the parent command pool. If this flag is not set, then the command buffer m= ay hold onto memory resources and reuse them when recording commands. commandBuffer is moved to the initia= l state.

typedef VkFlags VkCommandBufferResetFlags;

VkCommandBufferResetFlags is a bitmask type for setting a m= ask of zero or more VkCommandBufferResetFlagBits.

To free command buffers, call:

void vkFreeCommandBuffers(
    VkDevice                                    device,
    VkCommandPool                               commandPool,
    uint32_t                                    commandBufferCount,
    const VkCommandBuffer*                =
      pCommandBuffers);
  • device is the logical device that owns the command pool.

  • commandPool is the command pool from which the command buff= ers were allocated.

  • commandBufferCount is the length of the pCommandBuffe= rs array.

  • pCommandBuffers is an array of handles of command buffers t= o free.

Any primary command buffer that is in the reco= rding or executable state and has any element of pCommandBuffers<= /code> recorded into it, becomes invalid.

Valid Usage
  • All elements of pCommandBuffers must<= /strong> not be in the pending state

  • pCommandBuffers must be a va= lid pointer to an array of commandBufferCount VkCommandBuffer handles, each = element of which must either be a valid handle or NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • com= mandPool must be a valid VkC= ommandPool handle

  • = commandBufferCount must be g= reater than 0

  • comman= dPool must have been created, allo= cated, or retrieved from device

  • Each ele= ment of pCommandBuffers that is a valid handle must have been created, allocated, or retrieved from <= code>commandPool

Host Synchronization
  • Host access to commandPool must be externally synchronized

  • Host access to each member of pCommandBuffers must be externally synchronized

5.4. Command Buffer Recording

To begin recording a command buffer, call:

VkResult vkBeginCo=
mmandBuffer(
    VkCommandBuffer                             commandBuffer,
    const VkCommandBufferBeginInfo*       =
      pBeginInfo);
  • commandBuffer is the handle of the command buffer which is = to be put in the recording state.

  • pBeginInfo is an instance of the = VkCommandBufferBeginInfo structure, which defines additional information about how the command buffer begins recording.

Valid Usage
  • commandBuffer must not be in= the recording or pending state.

  • If commandBuffer was allocated from a VkCommand= Pool which did not have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag set, commandBuffer must= be in the initial state.

  • If commandBuffer is a secondary command buffer, the pInheritanceInfo member of pBeginInfo must be a valid VkCommandBufferInheritanceInfo structure

  • If commandBuffer is a secondary command buffer and either the occlusionQueryEnable member of the pInheritanceInfo member of pBeginInfo is VK_FALSE, or the precise occlusi= on queries feature is not enabled, the queryFlags member of the pInheritanceInfo member pBeginInfo must not contain VK_QUERY_CONTROL_PRECISE_BIT

Valid Usage (Implicit)
  • c= ommandBuffer must be a valid VkCommandBuffer handle

  • pBeg= inInfo must be a valid pointer to = a valid VkCommandBufferBeginInfo structure

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkCommandBufferBeginInfo structure is defined as:

typedef struct VkCommandBufferB=
eginInfo {
    VkStructureType                          sType;
    const void*                              pNext;
    VkCommandBufferUsageFlags                flags;
    const VkCommandBufferInheritanceInfo* =
   pInheritanceInfo;
} VkCommandBufferBeginInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkComma= ndBufferUsageFlagBits specifying usage behavior for the command buffer.

  • pInheritanceInfo is a pointer to a VkCommandBufferInheritanceInfo structure, which is used if commandBuffer is a secondary command buffer. If this is a primary command buffer, then this value is ignored.

Valid Usage
  • If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the renderPass member of pInheritanceInfo must be a valid VkRenderPass

  • If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the subpass member of pInheritanceInfo must be a valid subpass index within the renderPass member of pInheritanceInfo

  • If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the framebuffer member of pInheritanceInfo must be either VK_NULL_HANDLE, or a valid VkFramebuffer t= hat is compatible with the renderPass member of pInheritanceInfo

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_COMMA= ND_BUFFER_BEGIN_INFO

  • pNext must be NULL or a pointe= r to a valid instance of VkDeviceGroup= CommandBufferBeginInfo

  • flags= must be a valid combination of VkCommandBufferUsageFlagBits values

Bits which can be set in VkCommandBufferBeginInfo::flags to specify usage behavior for a command buffer are:

typedef enum VkCommandBufferUsa=
geFlagBits {
    VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT =3D 0x0=
0000001,
    VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT =3D 0x00000002,
    VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT =3D 0x=
00000004,
} VkCommandBufferUsageFlagBits;
  • VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT specifies that = each recording of the command buffer will only be submitted once, and the command buffer will be reset and recorded again between each submission.

  • VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT specifies = that a secondary command buffer is considered to be entirely inside a render pass. If this is a primary command buffer, then this bit is ignored.

  • VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT specifies that= a command buffer can be resubmitted to a qu= eue while it is in the pending state, and recorded into multiple primary command buffers.=

typedef VkFlags VkCommandBufferUsageFlags;

VkCommandBufferUsageFlags is a bitmask type for setting a m= ask of zero or more VkCommandBufferUsageFlagBits.

If the command buffer is a secondary command buffer, then the VkCommandBufferInheritanceInfo structure defines any state tha= t will be inherited from the primary command buffer:

typedef struct VkCommandBufferI=
nheritanceInfo {
    VkStructureType                  sType;
    const void*                      pNext;
    VkRenderPass                     renderPass;
    uint32_t                         subpass;
    VkFramebuffer                    framebuffer;
    VkBool32                         occlusionQueryEnable;
    VkQueryControlFlags              queryFlags;
    VkQueryPipelineStatisticFlags    pipelineStatistics;
} VkCommandBufferInheritanceInfo;
Valid Usage
Valid Usage (Implicit)
  • sTy= pe must be VK_STRUCTURE_TYPE= _COMMAND_BUFFER_INHERITANCE_INFO

  • pNe= xt must be NULL or a = pointer to a valid instance of VkCommandBufferInheritanceConditionalRenderingInfoEXT

  • Both of = framebuffer, and renderPass that are valid handle= s must have been created, allocated, or r= etrieved from the same VkDevice

If VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT was not set= when creating a command buffer, that command buffer mus= t not be submitted to a queue whilst it is already in the pending state. If VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT is not set on = a secondary command buffer, that command buffer must= not be used more than once in a given primary command buffer.

Note

On some implementations, not using the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT bit enables comma= nd buffers to be patched in-place if needed, rather than creating a copy of th= e command buffer.

If a command buffer is in the invalid, or executable state, and the command buffer was allocated from a command p= ool with the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag = set, then vkBeginCommandBuffer implicitly resets the command buffer= , behaving as if vkResetCommandBuffer had been called with VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT not set. After the implicit reset, commandBuffer is moved to the recording state.

If the pNext chain of VkCom= mandBufferInheritanceInfo includes a VkCommandBufferInheritanceConditionalRenderingInfoEXT structur= e, then that structure controls whether a command buffer c= an be executed while conditional rendering is active in the primary command buffer.

The VkCommandBufferInheritanceConditionalRenderingInfoEXT s= tructure is defined as:

typedef struct VkCommandBufferI=
nheritanceConditionalRenderingInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    VkBool32           conditionalRenderingEnable;
} VkCommandBufferInheritanceConditionalRenderingInfoEXT;
  • sType is the type of this structure

  • pNext is NULL or a pointer to an extension-spe= cific structure

  • conditionalRenderingEnable specifies whether the command bu= ffer can be executed while conditional renderi= ng is active in the primary command buffer. If this is VK_TRUE, then this command buffer can be executed whether the primary command buffer has active conditional rendering or not. If this is VK_FALSE, then the primary command buffer must not have conditional rendering active.

If this structure is not present, the behavior is as if conditionalRenderingEnable is VK_FALSE.

Valid Usage
Valid Usage (Implicit)
  • sType must be = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_IN= FO_EXT

Once recording starts, an application records a sequence of commands (vkCmd*) to set state in the command buffer, draw, dispatch, a= nd other commands.

Several commands can also be recorded indirectly from VkBuffer content, see Device-Generated Commands.

To complete recording of a command buffer, call:

VkResult vkEndComm=
andBuffer(
    VkCommandBuffer                             commandBuffer);
  • commandBuffer is the command buffer to complete recording.<= /p>

If there was an error during recording, the application will be notified= by an unsuccessful return code returned by vkEndCommandBuffer. If the application wishes to further use the command buffer, the command buffer must be reset. The command buffer must have been in the = recording state, and is moved to the executable state.

Valid Usage
Valid Usage (Implicit)
  • com= mandBuffer must be a valid V= kCommandBuffer handle

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

When a command buffer is in the executable state, it can be submitted to a queue for execution.

5.5. Command Buffer Submission

To submit command buffers to a queue, call:

VkResult vkQueueSu=
bmit(
    VkQueue                                     queue,
    uint32_t                                    submitCount,
    const VkSubmitInfo*                   =
      pSubmits,
    VkFence                                     fence);
  • queue is the queue that the command buffers will be submitt= ed to.

  • submitCount is the number of elements in the pSubmits= array.

  • pSubmits is a pointer to an array of VkSubmit= Info structures, each specifying a command buffer submission batch.

  • fence is an optional hand= le to a fence to be signaled once all submitted command buffers have completed execution. If fence is not VK_NULL_HANDLE, it defines= a fence signal operation.

Note

Submission can be a high overhead operation, and applications should attempt to batch work together into as few calls to vkQueueSubmit as possible.

vkQueueSubmit is a queue submissi= on command, with each batch defined by an element of pSubmits= as an instance of the VkSubmitInfo structure. Batches begin execution in the order they appear in pSubmits, = but may complete out of order.

Fence and semaphore operations submitted with vkQueueSubm= it have additional ordering constraints compared to other submission commands, with dependencies involving previous and subsequent queue operations. Information about these additional constraints can be found in the semaphore and fence= sections of the synchronization chapter.

Details on the interaction of pWaitDstStageMask with synchr= onization are described in the semaphore wait operation section of the synchronization chapter.<= /p>

The order that batches appear in pSubmits is used to determ= ine submission order, and thus all the implicit ordering guarantees that respect it. Other than these implicit ordering guarantees and any expl= icit synchronization primitives, these batches may overlap or otherwise execute out of order.

If any command buffer submitted to this queue is in the executable state, it is moved to the pending state. Once execution of all submissions of a command buffer complete, it moves from the pending state, back to the executable state. If a command buffer was recorded with the VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT flag, it instead m= oves back to the invalid state.

If vkQueueSubmit fails, it may return VK_ERROR_OUT_OF_HOST_MEMORY or VK_ERROR_OUT_OF_DEVICE_ME= MORY. If it does, the implementation must ensur= e that the state and contents of any resources or synchronization primitives referenced by the submitted command buffers and any semaphores referenced by pSubmits is unaffected by the call or its failure. If vkQueueSubmit fails in such a way that the implementation i= s unable to make that guarantee, the implementation must return VK_ERROR_DEVICE_LOST. See Lost Device.

Valid Usage
  • If fence is not VK_NULL_HANDLE, fenc= e must be unsignaled

  • If fence is not VK_NULL_HANDLE, fenc= e must not be associated with any other queue command that has not yet completed execution on that queue

  • Any calls to vkCmdSetEvent, vkCmdResetE= vent or vkCmdWaitEvents that have been recorded into any of th= e command buffer elements of the pCommandBuffers member of any element o= f pSubmits, must not reference= any VkEvent that is referenced by any of those commands in a command buffer that has been submitted to another queue and is still in the pending state.

  • Any stage flag included in any element of the pWaitDstStageMask member of any element of pSubmits mus= t be a pipeline stage supported by one of the capabilities of queue, as specified in= the table of supported pipeline stages.

  • Each element of the pSignalSemaphores member of any element of pSubmits must be unsignaled = when the semaphore signal operation it defines is executed on the device

  • When a semaphore unsignal operation defined by any element of the pWaitSemaphores member of any element of pSubmits= executes on queue, no other queue must be waiting on the same semaphore.

  • All elements of the pWaitSemaphores member of all elements of pSubmits must be semaphores = that are signaled, or have semaphore signal operations previously submitted for execution.

  • Each element of the pCommandBuffers member of each element of pSubmits must be in the pending or executable state.

  • If any element of the pCommandBuffers member of any element of pSubmits was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must not be in the pending state.

  • Any secondary command buffers recorded into any element of the pCommandBuffers member of any element = of pSubmits must be in the pending or executable state.

  • If any secondary command buffers recorded into any element of the pCommandBuffers member of any element = of pSubmits was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must not be in the pending state.

  • Each element of the pCommandBuffers member of each element of pSubmits must have been allo= cated from a VkCommandPool that was created for the same queue family queue belongs to.

  • If any element of pSubmits=E2=86=92pCommandBuffers includes a Queue Family Transfer Acquire Operation, there must exist a previou= sly submitted Queue Family Transfer Release Operation on a queue in the queue family identified by the acquire operation, with parameters matching the acquire operation as defined in the definition of such acquire ope= rations, and which happens before the acquire operation.

Valid Usage (Implicit)
  • queue must be a valid VkQueue handle<= /p>

  • If submitCoun= t is not 0, pSubmits must be a valid pointer to an array of submitCount valid VkSubmitInfo structures

  • If fence = is not VK_NULL_HANDLE, fence must be a valid VkFence handle

  • Both of fence, and queue that are valid handles m= ust have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to queue must= be externally synchronized

  • Host access to pSubmits[].pWaitSemaphores[] must be externally synchronized

  • Host access to pSubmits[].pSignalSemaphores[] must be externally synchronized

  • Host access to fence must= be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

The VkSubmitInfo structure is defined as:

typedef struct VkSubmitInfo {
    VkStructureType                sType;
    const void*                    pNext;
    uint32_t                       waitSemaphoreCount;
    const VkSemaphore*             pWaitSe=
maphores;
    const VkPipelineStageFlags*    pWaitDs=
tStageMask;
    uint32_t                       commandBufferCount;
    const VkCommandBuffer*         pComman=
dBuffers;
    uint32_t                       signalSemaphoreCount;
    const VkSemaphore*             pSignal=
Semaphores;
} VkSubmitInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • waitSemaphoreCount is the number of semaphores upon which t= o wait before executing the command buffers for the batch.

  • pWaitSemaphores is a pointer to an array of semaphores upon= which to wait before the command buffers for this batch begin execution. If semaphores to wait on are provided, they define a semaphore wait operation.

  • pWaitDstStageMask is a pointer to an array of pipeline stag= es at which each corresponding semaphore wait will occur.

  • commandBufferCount is the number of command buffers to exec= ute in the batch.

  • pCommandBuffers is a pointer to an array of command buffers= to execute in the batch.

  • signalSemaphoreCount is the number of semaphores to be sign= aled once the commands specified in pCommandBuffers have completed execution.

  • pSignalSemaphores is a pointer to an array of semaphores wh= ich will be signaled when the command buffers for this batch have completed execution. If semaphores to be signaled are provided, they define a semaphore signal operation.

The order that command buffers appear in pCommandBuffers is= used to determine submission order, and thus all the implicit ordering guarantees that respect it. Other than these implicit ordering guarantees and any expl= icit synchronization primitives, these command buffers may overlap or otherwise execute out of order.

Valid Usage
  • Each element of pCommandBuffers must<= /strong> not have been allocated with VK_COMMAND_BUFFER_LEVEL_SECONDARY

  • If the geometry shaders feature is not enabled, each element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the tessellation shaders feature is not enabled, each element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • Each element of pWaitDstStageMask mus= t not include VK_PIPELINE_STAGE_HOST_BIT.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_SUBMIT_INFO

  • Each pNext mem= ber of any structure (including this one) in the pNext chain <= strong class=3D"purple">must be either NULL or a poin= ter to a valid instance of VkD3D12FenceSubmitInf= oKHR, VkDeviceGroupSubmitInfo, VkProtectedSubmitInfo, VkWin32KeyedMutexAcquireReleaseInfoKHR, or VkWin32KeyedMutexAcquireReleaseInfoNV

  • Each sType me= mber in the pNext chain must= be unique

  • If wait= SemaphoreCount is not 0, pWaitSemaphores <= strong class=3D"purple">must be a valid pointer to an array of waitSemaphoreCount valid VkSemaphore handles

  • If wa= itSemaphoreCount is not 0, pWaitDstStageMask must be a valid pointer to an array of= waitSemaphoreCount valid combinations of VkPipelineStageFlagBits values

  • Each = element of pWaitDstStageMask must not be 0

  • If comm= andBufferCount is not 0, pCommandBuffers <= strong class=3D"purple">must be a valid pointer to an array of commandBufferCount valid VkCommandBuffer handles

  • If si= gnalSemaphoreCount is not 0, pSignalSemaphores must be a valid pointer to an array = of signalSemaphoreCount valid VkSemaphore handles=

  • Each of the elements of pCommandBuffers, the elements of pSignalSemaphores,= and the elements of pWaitSemaphores that are valid handles must have been created, allocated, or retri= eved from the same VkDevice

To specify the values to use when waiting for and signaling semaphores w= hose current payload refers to a Direct3D 12 fence, add the VkD3D12FenceSubmitInf= oKHR structure to the pNext chain of the VkSubmitInfo structure. The VkD3D12FenceSubmitInfoKHR structure is defined as:

typedef struct VkD3D12FenceSubm=
itInfoKHR {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           waitSemaphoreValuesCount;
    const uint64_t*    pWaitSemaphoreValue=
s;
    uint32_t           signalSemaphoreValuesCount;
    const uint64_t*    pSignalSemaphoreVal=
ues;
} VkD3D12FenceSubmitInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • waitSemaphoreValuesCount is the number of semaphore wait va= lues specified in pWaitSemaphoreValues.

  • pWaitSemaphoreValues is an array of length waitSemaphoreValuesCount containing values for the correspondi= ng semaphores in VkSubmitInfo::pWaitSemaphores = to wait for.

  • signalSemaphoreValuesCount is the number of semaphore signa= l values specified in pSignalSemaphoreValues.

  • pSignalSemaphoreValues is an array of length signalSemaphoreValuesCount containing values for the correspon= ding semaphores in VkSubmitInfo::pSignalSemaphores to set when signaled.

If the semaphore in VkSubmitInfo::pWaitSemaphore= s or VkSubmitInfo::pSignalSemaphores correspondin= g to an entry in pWaitSemaphoreValues or pSignalSemaphoreValues re= spectively does not currently have a payload referring to a Direct3D 12 fence, the implementation must ignore the value in the pWaitSemaphoreValues or pSignalSemaphoreValues entry.

Valid Usage
  • = waitSemaphoreValuesCount must be the same value as VkSubmitInfo::waitSemaphoreCount, where VkS= ubmitInfo is in the pNext chain of this VkD3D12FenceSubmitInfoKHR<= /code> structure.

  • signalSemaphoreValuesCount must be the same value as VkSubmitInfo::signalSemaphoreCount, where V= kSubmitInfo is in the pNext chain of this VkD3D12FenceSubmitInfoKHR<= /code> structure.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_D3D1= 2_FENCE_SUBMIT_INFO_KHR

  • = If waitSemaphoreValuesCount is not 0, and pWaitSemaphoreValues is not NULL, pWaitSemaph= oreValues must be a valid pointer = to an array of waitSemaphoreValuesCount uint64_t = values

  • If signalSemaphoreValuesCount is not 0, an= d pSignalSemaphoreValues is not NULL, pSign= alSemaphoreValues must be a valid = pointer to an array of signalSemaphoreValuesCount uint64= _t values

When submitting work that operates on memory imported from a Direct3D 11 resource to a queue, the keyed mutex mechanism may= be used in addition to Vulkan semaphores to synchronize the work. Keyed mutexes are a property of a properly created shareable Direct3D 11 resource. They can only be used if the imported res= ource was created with the D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX flag.

To acquire keyed mutexes before submitted work and/or release them after= , add a VkWin32KeyedMutexAcquireRelea= seInfoKHR structure to the pNext chain of the VkSubmitInfo structure.

The VkWin32KeyedMutexAcquireReleaseInfoKHR structure is def= ined as:

typedef struct VkWin32KeyedMute=
xAcquireReleaseInfoKHR {
    VkStructureType          sType;
    const void*              pNext;
    uint32_t                 acquireCount;
    const VkDeviceMemory*    pAcquireSyncs=
;
    const uint64_t*          pAcquireKeys;
    const uint32_t*          pAcquireTimeo=
uts;
    uint32_t                 releaseCount;
    const VkDeviceMemory*    pReleaseSyncs=
;
    const uint64_t*          pReleaseKeys;
} VkWin32KeyedMutexAcquireReleaseInfoKHR;
  • acquireCount is the number of entries in the pAcquire= Syncs, pAcquireKeys, and pAcquireTimeoutMilliseconds arr= ays.

  • pAcquireSyncs is a pointer to an array of V= kDeviceMemory objects which were imported from Direct3D 11 resources.

  • pAcquireKeys is a pointer to an array of mutex key values t= o wait for prior to beginning the submitted work. Entries refer to the keyed mutex associated with the corresponding entries in pAcquireSyncs.

  • pAcquireTimeoutMilliseconds is an array of timeout values, = in millisecond units, for each acquire specified in pAcquireKeys.=

  • releaseCount is the number of entries in the pRelease= Syncs and pReleaseKeys arrays.

  • pReleaseSyncs is a pointer to an array of V= kDeviceMemory objects which were imported from Direct3D 11 resources.

  • pReleaseKeys is a pointer to an array of mutex key values t= o set when the submitted work has completed. Entries refer to the keyed mutex associated with the corresponding entries in pReleaseSyncs.

Valid Usage
  • Each member of pAcquireSyncs and pReleaseSyncs must be a device memory object imported by setting VkImportMemoryWin32HandleInfoKHR::handleType to VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT or VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT.

Valid Usage (Implicit)
  • <= code>sType must be VK_STRUCT= URE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR

  • If acquireCount is not 0, pAcqui= reSyncs must be a valid pointer to= an array of acquireCount valid VkDeviceMemory ha= ndles

  • If acquireCount is not 0, pAcquir= eKeys must be a valid pointer to a= n array of acquireCount uint64_t values

  • If acquireCount is not 0, pAc= quireTimeouts must be a valid poin= ter to an array of acquireCount uint32_t values

  • If releaseCount is not 0, pRelea= seSyncs must be a valid pointer to= an array of releaseCount valid VkDeviceMemory ha= ndles

  • If releaseCount is not 0, pReleas= eKeys must be a valid pointer to a= n array of releaseCount uint64_t values

  • = Both of the elements of pAcquireSyncs, and the elements of pReleaseSyncs that are valid handles mus= t have been created, allocated, or retrieved from the same V= kDevice

When submitting work that operates on memory imported from a Direct3D 11 resource to a queue, the keyed mutex mechanism may= be used in addition to Vulkan semaphores to synchronize the work. Keyed mutexes are a property of a properly created shareable Direct3D 11 resource. They can only be used if the imported res= ource was created with the D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX flag.

To acquire keyed mutexes before submitted work and/or release them after= , add a VkWin32KeyedMutexAcquireReleas= eInfoNV structure to the pNext chain of the VkSubmitInfo structure.

The VkWin32KeyedMutexAcquireReleaseInfoNV structure is defi= ned as:

typedef struct VkWin32KeyedMute=
xAcquireReleaseInfoNV {
    VkStructureType          sType;
    const void*              pNext;
    uint32_t                 acquireCount;
    const VkDeviceMemory*    pAcquireSyncs=
;
    const uint64_t*          pAcquireKeys;
    const uint32_t*          pAcquireTimeo=
utMilliseconds;
    uint32_t                 releaseCount;
    const VkDeviceMemory*    pReleaseSyncs=
;
    const uint64_t*          pReleaseKeys;
} VkWin32KeyedMutexAcquireReleaseInfoNV;
  • acquireCount is the number of entries in the pAcquireSyncs, pAcquireKeys, and pAcquireTimeoutMilliseconds arrays.

  • pAcquireSyncs is a pointer to an array of V= kDeviceMemory objects which were imported from Direct3D 11 resources.

  • pAcquireKeys is a pointer to an array of mutex key values t= o wait for prior to beginning the submitted work. Entries refer to the keyed mutex associated with the corresponding entries in pAcquireSyncs.

  • pAcquireTimeoutMilliseconds is an array of timeout values, = in millisecond units, for each acquire specified in pAcquireKeys.=

  • releaseCount is the number of entries in the pRelease= Syncs and pReleaseKeys arrays.

  • pReleaseSyncs is a pointer to an array of V= kDeviceMemory objects which were imported from Direct3D 11 resources.

  • pReleaseKeys is a pointer to an array of mutex key values t= o set when the submitted work has completed. Entries refer to the keyed mutex associated with the corresponding entries in pReleaseSyncs.

Valid Usage (Implicit)
  • sType must be VK_STRUCTU= RE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV

  • If acquireCount is not 0, pAcquir= eSyncs must be a valid pointer to = an array of acquireCount valid VkDeviceMemory han= dles

  • If acquireCount is not 0, pAcquire= Keys must be a valid pointer to an= array of acquireCount uint64_t values

  • If acquireCount is not 0,= pAcquireTimeoutMilliseconds must be a valid pointer to an array of acquireCount uin= t32_t values

  • If releaseCount is not 0, pReleas= eSyncs must be a valid pointer to = an array of releaseCount valid VkDeviceMemory han= dles

  • If releaseCount is not 0, pRelease= Keys must be a valid pointer to an= array of releaseCount uint64_t values

  • B= oth of the elements of pAcquireSyncs, and the elements of pReleaseSyncs that are valid handles must= have been created, allocated, or retrieved from the same Vk= Device

If the pNext chain of VkSubmitInfo includ= es a VkProtectedSubmitInfo structure, then the structure indicates = whether the batch is protected. The VkProtectedSubmitInfo structure is defined as:

typedef struct VkProtectedSubmi=
tInfo {
    VkStructureType    sType;
    const void*        pNext;
    VkBool32           protectedSubmit;
} VkProtectedSubmitInfo;
  • protectedSubmit specifies whether the batch is protected. If protectedSubmit is VK_TRUE, the batch is prote= cted. If protectedSubmit is VK_FALSE, the batch is unpr= otected. If the VkSubmitInfo::pNext chain does not contain= this structure, the batch is unprotected.

Valid Usage
  • If the protected memory feature is not enabled, protectedSubmit must not be VK_TRUE.

  • If protectedSubmit is VK_TRUE, then each element = of the pCommandBuffers array must b= e a protected command buffer.

  • If protectedSubmit is VK_FALSE, then each element= of the pCommandBuffers array must b= e an unprotected command buffer.

  • If the VkSubmitInfo::pNext chain does not include= a VkProtectedSubmitInfo structure, then each element of the comm= and buffer of the pCommandBuffers array m= ust be an unprotected command buffer.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_PROTECTE= D_SUBMIT_INFO

If the pNext chain of VkSubmitInfo includ= es a VkDeviceGroupSubmitInfo structure, then that structure include= s device indices and masks specifying which physical devices execute semaphore operations and command buffers.

The VkDeviceGroupSubmitInfo structure is defined as:

typedef struct VkDeviceGroupSub=
mitInfo {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           waitSemaphoreCount;
    const uint32_t*    pWaitSemaphoreDevic=
eIndices;
    uint32_t           commandBufferCount;
    const uint32_t*    pCommandBufferDevic=
eMasks;
    uint32_t           signalSemaphoreCount;
    const uint32_t*    pSignalSemaphoreDev=
iceIndices;
} VkDeviceGroupSubmitInfo;

or the equivalent

typedef VkDeviceGroupSubmitInfo VkDeviceGroupSubmitInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • waitSemaphoreCount is the number of elements in the pWaitSemaphoreDeviceIndices array.

  • pWaitSemaphoreDeviceIndices is an array of device indices indicating which physical device executes the semaphore wait operation in the corresponding element of VkSubmitInfo::pWaitSemaphores.

  • commandBufferCount is the number of elements in the pCommandBufferDeviceMasks array.

  • pCommandBufferDeviceMasks is an array of device masks indic= ating which physical devices execute the command buffer in the corresponding element of VkSubmitInfo::pCommandBuffers. A physical device executes the command buffer if the corresponding bit is set in the mask.

  • signalSemaphoreCount is the number of elements in the pSignalSemaphoreDeviceIndices array.

  • pSignalSemaphoreDeviceIndices is an array of device indices indicating which physical device executes the semaphore signal operation in the corresponding element of VkSubmitInfo::pSignalSemaphores.

If this structure is not present, semaphore operations and command buffe= rs execute on device index zero.

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEVICE= _GROUP_SUBMIT_INFO

  • If waitSemaphoreCount is not 0, p= WaitSemaphoreDeviceIndices must be= a valid pointer to an array of waitSemaphoreCount uint3= 2_t values

  • If commandBufferCount is not 0, pCo= mmandBufferDeviceMasks must be a v= alid pointer to an array of commandBufferCount uint32_t<= /code> values

  • If signalSemaphoreCount is not 0, pSignalSemaphoreDeviceIndices must be a valid pointer to an array of signalSemaphoreCount uint32_t values

5.6. Queue Forward Progress

The application must ensure that comma= nd buffer submissions will be able to complete without any subsequent operations by the application on any queue. After any call to vkQueueSubmit, for every queued wait on a se= maphore there must be a prior signal of that sema= phore that will not be consumed by a different wait on the semaphore.

Command buffers in the submission can = include vkCmdWaitEvents commands that wait on events that will not be signaled by earlier commands in the queue. Such events must be signaled by the appli= cation using vkSetEvent, and the vkCmdWaitEvents commands that wait upon them must not be inside a render pass instance. Implementations may have limits on how lo= ng the command buffer will wait, in order to avoid interfering with progress of other clients of the device. If the event is not signaled within these limits, results are undefined and may include device loss.

5.7. Secondary Command Buffer Execution=

A secondary command buffer must not be= directly submitted to a queue. Instead, secondary command buffers are recorded to execute as part of a primary command buffer with the command:

void vkCmdExecuteCommands(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    commandBufferCount,
    const VkCommandBuffer*                =
      pCommandBuffers);
  • commandBuffer is a handle to a primary command buffer that = the secondary command buffers are executed in.

  • commandBufferCount is the length of the pCommandBuffe= rs array.

  • pCommandBuffers is an array of secondary command buffer han= dles, which are recorded to execute in the primary command buffer in the order they are listed in the array.

If any element of pCommandBuffers was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, and it was = recorded into any other primary command buffer which is currently in the executable or recording state, that primary command buffer becomes invalid.

Valid Usage
  • commandBuffer must have been= allocated with a level of VK_COMMAND_BUFFER_LEVEL_PRIMARY

  • Each element of pCommandBuffers must<= /strong> have been allocated with a level of VK_COMMAND_BUFFER_LEVEL_SECONDARY

  • Each element of pCommandBuffers must<= /strong> be in the pending or executable state.

  • If any element of pCommandBuffers was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, and it was recorded into any other primary command buffer, that primary command buffer must not be in the pending state

  • If any element of pCommandBuffers was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, it must not be in the pending state.

  • If any element of pCommandBuffers was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, it must not have already been recorded to commandBuffer.

  • If any element of pCommandBuffers was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, it must not appear more than once in pCommandBuffers.

  • Each element of pCommandBuffers must<= /strong> have been allocated from a VkCommandPool that was created for the same queue family as th= e VkCommandPool from which commandBuffer was alloca= ted

  • If vkCmdExecuteCommands is being called within a render pass instance, that render pass instance must = have been begun with the contents parameter of vkCmdBeginRenderPass set to VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS

  • If vkCmdExecuteCommands is being called within a render pass instance, each element of pCommandBuffers must have been recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT

  • If vkCmdExecuteCommands is being called within a render pass instance, each element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::subpass set = to the index of the subpass which the given command buffer will be executed in

  • If vkCmdExecuteCommands is being called within a render pass instance, the render passes specified in the pBeginInfo::pInheritanceInfo::renderPass members of the vkBeginCommandBuffer commands used to begin r= ecording each element of pCommandBuffers must be compatible with the current render pass.

  • If vkCmdExecuteCommands is being called within a render pass instance, and any element of pCommandBuffers was recorded with VkCommandBufferInheritanceInfo::framebuffer not e= qual to VK_NULL_HANDLE, that VkFramebuffer must match the VkFramebuffer used in the current render pass instance

  • If vkCmdExecuteCommands is not being called within a render pa= ss instance, each element of pCommandBuffers must not have been recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT

  • If the inherited queries feature is not enabled, commandBuffer must not have any queries active

  • If commandBuffer has a VK_QUERY_TYPE_OCCLUSION qu= ery active, then each element of pCommandBuffers must have be= en recorded with VkCommandBufferInheritanceInfo::occlusionQueryEnable set to VK_TRUE

  • If commandBuffer has a VK_QUERY_TYPE_OCCLUSION qu= ery active, then each element of pCommandBuffers must have be= en recorded with VkCommandBufferInheritanceInfo::queryFlags having= all bits set that are set for the query

  • If commandBuffer has a VK_QUERY_TYPE_PIPELINE_STATISTICS= query active, then each element of pCommandBuffers must have be= en recorded with VkCommandBufferInheritanceInfo::pipelineStatistics having all bits set that are set in the VkQueryPool the query uses

  • Each element of pCommandBuffers must<= /strong> not begin any query types that are active in commandBuffer=

  • If commandBuffer is a protected command buffer, then each elem= ent of pCommandBuffers must be a= protected command buffer.

  • If commandBuffer is an unprotected command buffer, then each element of pCommandBuffers must be an unprotected command buffer.

Valid Usage (Implicit)
  • c= ommandBuffer must be a valid VkCommandBuffer handle

  • pCommandBuffers must be a valid p= ointer to an array of commandBufferCount valid VkCommand= Buffer handles

  • c= ommandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute= operations

  • commandBuffer= must be a primary VkCommand= Buffer

  • = commandBufferCount must be g= reater than 0

  • Both of comm= andBuffer, and the elements of pCommandBuffers must have been created, allocated, or retrieved f= rom the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary

Bot= h

Tra= nsfer
Graphics
Compute

5.8. Command Buffer Device Mask

Each command buffer has a piece of state storing the current device mask= of the command buffer. This mask controls which physical devices within the logical device all subsequent commands will execute on, including state-setting commands, action commands, and synchronization commands.

Scissor and viewport state can be set = to different values on each physical device (only when set as dynamic state), and each physical device will render using its local copy of the state. Other state is shared between physical devices, such that all physical devices use the most recently set values for the state. However, when recording an action command that uses a piece of state, the most recent command that set that state must have included all physical devices that execute the action command in its current device mask.

The command buffer=E2=80=99s device mask is orthogonal to the pCommandBufferDeviceMasks member of V= kDeviceGroupSubmitInfo. Commands only execute on a physical device if the device index is set in both device masks.

If the pNext chain of VkCommandBu= fferBeginInfo includes a VkDeviceGroupCommandBufferBeginInfo structure, then that struc= ture includes an initial device mask for the command buffer.

The VkDeviceGroupCommandBufferBeginInfo structure is define= d as:

typedef struct VkDeviceGroupCom=
mandBufferBeginInfo {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           deviceMask;
} VkDeviceGroupCommandBufferBeginInfo;

or the equivalent

typedef VkDeviceGroupCommandBufferBeginInfo VkDeviceGroupComma=
ndBufferBeginInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • deviceMask is the initial value of the command buffer=E2=80= =99s device mask.

The initial device mask also acts as an upper bound on the set of device= s that can ever be in the device mask in th= e command buffer.

If this structure is not present, the initial value of a command buffer= =E2=80=99s device mask is set to include all physical devices in the logical device when the command buffer begins recording.

Valid Usage
  • deviceMask must be a valid d= evice mask value

  • deviceMask must not be zero<= /p>

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO

To update the current device mask of a command buffer, call:

void vkCmdSetDeviceMask(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    deviceMask);

or the equivalent command

void vkCmdSetDeviceMaskKHR(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    deviceMask);
  • commandBuffer is command buffer whose current device mask i= s modified.

  • deviceMask is the new value of the current device mask.

deviceMask is used to filter out subsequent commands from e= xecuting on all physical devices whose bit indices are not set in the mask.

Valid Usage
Valid Usage (Implicit)
  • com= mandBuffer must be a valid V= kCommandBuffer handle

  • com= mandBuffer must be in the recording state

  • The V= kCommandPool that commandBuffer was allocated from must support graphics, compute, or transfer o= perations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute
Transfer

6. Synchronization and Cache Control

Synchronization of access to resources is primarily the responsibility o= f the application in Vulkan. The order of execution of commands with respect to the host and other commands on the device has few implicit guarantees, and needs to be explicitly specified. Memory caches and other optimizations are also explicitly managed, requirin= g that the flow of data through the system is largely under application control.

Whilst some implicit guarantees exist between commands, five explicit synchronization mechanisms are exposed by Vulkan:

Fences

Fences can be used to communicate to t= he host that execution of some task on the device has completed.

Semaphores

Semaphores can be used to control reso= urce access across multiple queues.

Events

Events provide a fine-grained synchronization primitive which can be signaled either within a command buffer or by the host, and can be waited upon within a command buffer or queried on the host.

Pipeline Barriers<= /a>

Pipeline barriers also provide synchronization control within a command buffer, but at a single point, rather than with separate signal and wait operations.

Render Passes

Render passes provide a useful synchronization framework for most rendering tasks, built upon the concepts in this chapter. Many cases that would otherwise need an application to use other synchronization primitives can be express= ed more efficiently as part of a render pass.

6.1. Execution and Memory Dependenc= ies

An operation is an arbitrary amount of work to be executed on t= he host, a device, or an external entity such as a presentation engine. Synchronization commands introduce explicit execution dependencies= , and memory dependencies between two sets of operations defined by the command=E2=80=99s two synchronization scopes.

The synchronization scopes define which other operations a synchronizati= on command is able to create execution dependencies with. Any type of operation that is not in a synchronization command=E2=80=99s synchronization scopes will not be included in the resulting dependency. For example, for many synchronization commands, the synchronization scopes can be limited to just operations executi= ng in specific pipeline stages, which allows other pipeline stages to be excluded from a dependency. Other scoping options are possible, depending on the particular command.

An execution dependency is a guarantee that for two sets of ope= rations, the first set must happen-before= the second set. If an operation happens-before another operation, then the first operation must complete before the second operation= is initiated. More precisely:

  • Let A and B be separate sets of operat= ions.

  • Let S be a synchronization command.

  • Let AS and BS be= the synchronization scopes of S.

  • Let A' be the intersection of sets A a= nd AS.

  • Let B' be the intersection of sets B a= nd BS.

  • Submitting A, S and B= for execution, in that order, will result in execution dependency E between A' and B'.

  • Execution dependency E guarantees that A' happens-before B'.

An execution dependency chain is a sequence of execution depend= encies that form a happens-before relation between the first dependency=E2=80=99s A' and the final dependency=E2=80=99s B'. For each consecutive pair of execution dependencies, a chain exists if the intersection of BS in the first dependency and = AS in the second dependency is not an empty set. The formation of a single execution dependency from an execution dependency chain can be described by substituting the following in the description of execution dependencies:

  • Let S be a set of synchronization commands that generat= e an execution dependency chain.

  • Let AS be the first synchronization scope of= the first command in S.

  • Let BS be the second synchronization scope o= f the last command in S.

Note

An execution dependency is inherently also multiple execution dependenci= es - a dependency exists between each subset of A' and each sub= set of B', and the same is true for execution dependency chains. For example, a synchronization command with multiple pipeline stages in its stage masks effectively generates one dependency between each source stage and each destination stage. This can be useful to think about when considering how execution chains are formed if they do not involve all parts of a synchronization command=E2=80= =99s dependency. Similarly, any set of adjacent dependencies in an execution dependency chai= n can be considered an execution dependency= chain in its own right.

Execution dependencies alone are not sufficient to guarantee that values resulting from writes in one set of operations can= be read from another set of operations.

Two additional types of operation are used to control memory access. Availability operations cause the values generated by specified me= mory write accesses to become available for future access. Any available value remains available until a subsequent write to the same memory location occurs (whether it is made available or not) or the memory is freed. Visibility operations cause any available values to become vis= ible to specified memory accesses.

A memory dependency is an execution dependency which includes a= vailability and visibility operations such that:

  • The first set of operations happens-before the availability operation.

  • The availability operation happens-before the visibility operation.

  • The visibility operation happens-before the second set of operations.

Once written values are made visible to a particular type of memory acce= ss, they can be read or written by that type = of memory access. Most synchronization commands in Vulkan define a memory dependency.

The specific memory accesses that are made available and visible are def= ined by the access scopes of a memory dependency. Any type of access that is in a memory dependency=E2=80=99s first access sc= ope and occurs in A' is made available. Any type of access that is in a memory dependency=E2=80=99s second access s= cope and occurs in B' has any available writes made visible to it. Any type of operation that is not in a synchronization command=E2=80=99s ac= cess scopes will not be included in the resulting dependency.

A memory dependency enforces availability and visibility of memory acces= ses and execution order between two sets of operations. Adding to the description of execution= dependency chains:

  • Let a be the set of memory accesses performed by A'.

  • Let b be the set of memory accesses performed by B'.

  • Let aS be the first access scope of the firs= t command in S.

  • Let bS be the second access scope of the las= t command in S.

  • Let a' be the intersection of sets a a= nd aS.

  • Let b' be the intersection of sets b a= nd bS.

  • Submitting A, S and B= for execution, in that order, will result in a memory dependency m between A' and B'.

  • Memory dependency m guarantees that:

    • Memory writes in a' are made available.

    • Available memory writes, including those from a', are m= ade visible to b'.

Note

Execution and memory dependencies are used to solve data hazards, i.e. t= o ensure that read and write operations occur in a well-defined order. Write-after-read hazards can be solved with just an execution dependency, but read-after-write and write-after-write hazards need appropriate memory dependencies to be included between them. If an application does not include dependencies to solve these hazards, the results and execution orders of memory accesses are undefined.

6.1.1. Image Layout Tra= nsitions

Image subresources can be transitioned= from one layout to another as part of a memory dependency (e.g. by using an image memory barrier). When a layout transition is specified in a memory dependency, it happens-after the availability operations in the memory dependency, and happens-before the visibility operations. Image layout transitions may perform read= and write accesses on all memory bound to the image subresource range, so applications must ensure that all memory writes have been made available before a layout transition is executed. Available memory is automatically made visible to a layout transition, and writes performed by a layout transition are automatically made available.

Layout transitions always apply to a particular image subresource range,= and specify both an old layout and new layout. If the old layout does not match the new layout, a transition occurs. The old layout must match the current lay= out of the image subresource range, with one exception. The old layout can always be specified as= VK_IMAGE_LAYOUT_UNDEFINED, though doing so invalidates the contents of the image subresource range.

As image layout transitions may perfor= m read and write accesses on the memory bound to the image, if the image subresource affected by the layout transition is bound to peer memory for any device in the current device mas= k then the memory heap the bound memory comes from m= ust support the VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT and VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT capabilities as returne= d by vkGetDeviceGroupPeerMemoryFeatures.=

Note

Setting the old layout to VK_IMAGE_LAYOUT_UNDEFINED implies= that the contents of the image subresource need not be preserved. Implementations may use this information = to avoid performing expensive data transition operations.

Note

Applications must ensure that layout t= ransitions happen-after all operations accessing the image with the old layout, and happen-before any operations that will access the image with the new layout. Layout transitions are potentially read/write operations, so not defining appropriate memory dependencies to guarantee this will result in a data race.

Image layout transitions interact with memory aliasing.

6.1.2. Pipeline Stages

The work performed by an acti= on or synchronization command consists of multiple operations, which are performed as a sequence of logically independent steps known as pipelin= e stages. The exact pipeline stages executed depend on the particular command that is used, and current command buffer state when the command was recorded. Drawing commands, dispatching commands, copy commands, clear commands, and synchronization commands all execute in different sets of pipeline stages. Synchronization commands do not execute in a defined pipeline, but do execute VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT and VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT.

Note

Operations performed by synchronization commands (e.g. availability and visibility operations) are not executed by a defined pipeline stage. However other commands can still synchronize with them via the VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT and VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT pipeline stages.

Execution of operations across pipeline stages = must adhere to implicit ordering guarantees, particularly including pipeline stage order. Otherwise, execution across pipeline stages may overlap or execute out of order with regards to other stages, unless otherwise enforced by an execution dependency.

Several of the synchronization commands include pipeline stage parameter= s, restricting the synchronization scopes for that command to just those stages. This allows fine grained control over the exact execution dependencies and accesses performed by action commands. Implementations should use these pipeline= stages to avoid unnecessary stalls or cache flushing.

Bits which can be set, specifying pipeline stages, are:

typedef enum VkPipelineStageFla=
gBits {
    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT =3D 0x00000001,
    VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT =3D 0x00000002<=
/span>,
    VK_PIPELINE_STAGE_VERTEX_INPUT_BIT =3D 0x00000004,
    VK_PIPELINE_STAGE_VERTEX_SHADER_BIT =3D 0x00000008<=
/span>,
    VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT =3D 0x00000010,
    VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT =3D 0x00000020,
    VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT =3D 0x0000004=
0,
    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT =3D 0x0000008=
0,
    VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT =3D 0x00=
000100,
    VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT =3D 0x000=
00200,
    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT =3D 0=
x00000400,
    VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT =3D 0x00000800=
,
    VK_PIPELINE_STAGE_TRANSFER_BIT =3D 0x00001000,
    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT =3D 0x00002000=
,
    VK_PIPELINE_STAGE_HOST_BIT =3D 0x00004000,
    VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT =3D 0x00008000,
    VK_PIPELINE_STAGE_ALL_COMMANDS_BIT =3D 0x00010000,
    VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT =3D 0x00040000,
    VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX =3D 0x000=
20000,
} VkPipelineStageFlagBits;
  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT specifies the stage of th= e pipeline where any commands are initially received by the queue.

  • VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT specifies the stage of = the pipeline where Draw/DispatchIndirect data structures are consumed. This stage also includes reading commands written by vkCmdProcessCommandsNVX.

  • VK_PIPELINE_STAGE_VERTEX_INPUT_BIT specifies the stage of t= he pipeline where vertex and index buffers are consumed.

  • VK_PIPELINE_STAGE_VERTEX_SHADER_BIT specifies the vertex sh= ader stage.

  • VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT specifies= the tessellation control shader stage.

  • VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT specif= ies the tessellation evaluation shader stage.

  • VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT specifies the geometr= y shader stage.

  • VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT specifies the fragmen= t shader stage.

  • VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT specifies the st= age of the pipeline where early fragment tests (depth and stencil tests before fragment shading) are performed. This stage also includes subpass load operations for framebuffer attachments with a depth/stencil format.

  • VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT specifies the sta= ge of the pipeline where late fragment tests (depth and stencil tests after fragment shading) are performed. This stage also includes subpass store operations for framebuffer attachments with a depth/stencil format.

  • VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT specifies the= stage of the pipeline after blending where the final color values are output from the pipeline. This stage also includes subpass load and store operations and multisample resolve operations for framebuffer attachments with a color format.

  • VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT specifies the executio= n of a compute shader.

  • VK_PIPELINE_STAGE_TRANSFER_BIT specifies the execution of copy commands. This includes the operations resulting from all copy commands, clear commands (with the exception of vkCmdClearAttachments), and vkCmdCopyQueryPoolResults.

  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT specifies the final st= age in the pipeline where operations generated by all commands complete execution.

  • VK_PIPELINE_STAGE_HOST_BIT specifies a pseudo-stage indicat= ing execution on the host of reads/writes of device memory. This stage is not invoked by any commands recorded in a command buffer.

  • VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT specifies the execution = of all graphics pipeline stages, and is equivalent to the logical OR of:

    • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT

    • VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT

    • VK_PIPELINE_STAGE_VERTEX_INPUT_BIT

    • VK_PIPELINE_STAGE_VERTEX_SHADER_BIT

    • VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT

    • VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

    • VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

    • VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

    • VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT

    • VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT

    • VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

    • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

    • VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT

  • VK_PIPELINE_STAGE_ALL_COMMANDS_BIT is equivalent to the log= ical OR of every other pipeline stage flag that is supported on the queue it is used with.

  • VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT specifies t= he stage of the pipeline where the predicate of conditional rendering is consumed.

  • VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX specifies the sta= ge of the pipeline where device-side generation of commands via vkCmdProcessCommandsNVX is handled.

Note

An execution dependency with only VK_PIPELINE_STAGE_BOTTOM_OF_PIPE= _BIT in the destination stage mask will only prevent that stage from executing i= n subsequently submitted commands. As this stage does not perform any actual execution, this is not observable - in effect, it does not delay processing of subsequent commands. Similarly an execution dependency with only VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT in the source stage mask wil= l effectively not wait for any prior commands to complete.

When defining a memory dependency, using only VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT or VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT would never make any accesse= s available and/or visible because these stages do not access memory.

VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT and VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT are useful for accomplishing= layout transitions and queue ownership operations when the required execution dependency is satisfied by other means - for example, semaphore operations between queues.

typedef VkFlags VkPipelineStageFlags;

VkPipelineStageFlags is a bitmask type for setting a mask o= f zero or more VkPipelineStageFlagBits.

If a synchronization command includes a source stage mask, its first synchronization scope only include= s execution of the pipeline stages specified in that mask, and its first access scope only includes memory access performed by pipeline stages specified in that mask. If a synchronization command includes a destination stage mask, its second synchronization scope only include= s execution of the pipeline stages specified in that mask, and its second access scope only includes memory access performed by pipeline stages specified in that mask.

Note

Including a particular pipeline stage in the first synchronization scope of a command implicitly includes logically earlier pipeline stages in the synchronization scope. Similarly, the second synchronization scope includes logically later pipeline stages.

However, note that access scopes are not affected in this way - only the precise stages specified are considered part of each access scope.

Certain pipeline stages are only available on queues that support a particular set of operations. The following table lists, for each pipeline stage flag, which queue capability flag must be supported by the = queue. When multiple flags are enumerated in the second column of the table, it means that the pipeline stage is supported on the queue if it supports any of the listed capability flags. For further details on queue capabilities see Physical Device Enumeration and Queues.

Table 3. Supported pipeline stage flags
Pipeline stage flag Required queue capability f= lag

VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT

Non= e required

VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT

VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT

VK_PIPELINE_STAGE_VERTEX_INPUT_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_VERTEX_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT

VK_QUEUE_COMPUTE_BIT

VK_PIPELINE_STAGE_TRANSFER_BIT

VK_QUEUE_GRAPHICS_BIT, VK_QUEUE_COMPUTE_BIT or VK_QUEUE_TRANSFER_BIT

VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

Non= e required

VK_PIPELINE_STAGE_HOST_BIT

Non= e required

VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_ALL_COMMANDS_BIT

Non= e required

VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT

VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT

VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX

VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT

Pipeline stages that execute as a result of a command logically complete execution in a specific order, such that completion of a logically later pipeline stage must not happen-before com= pletion of a logically earlier stage. This means that including any stage in the source stage mask for a particular synchronization command also implies that any logically earlier stages are included in AS for that command.

Similarly, initiation of a logically earlier pipeline stage must not happen-after initiation of a logically later pipeline stage. Including any given stage in the destination stage mask for a particular synchronization command also implies that any logically later stages are included in BS for that command.

Note

Implementations may not support synchr= onization at every pipeline stage for every synchronization operation. If a pipeline stage that an implementation does not support synchronization for appears in a source stage mask, it may substitute any logically later stage in its place for the first synchronization scope. If a pipeline stage that an implementation does not support synchronization for appears in a destination stage mask, it may substitute any logically earlier stage in its place for the second synchronization scope.

For example, if an implementation is unable to signal an event immediate= ly after vertex shader execution is complete, it may<= /strong> instead signal the event after color attachment output has completed.

If an implementation makes such a substitution, it must not affect the semantics of execution or memory dependencies or image and buffer memory barriers.

The order and set of pipeline stages executed by a given command is determined by the command=E2=80=99s pipeline type, as described below:

For the graphics pipeline, the following stages occur in this order:

  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT

  • VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT

  • VK_PIPELINE_STAGE_VERTEX_INPUT_BIT

  • VK_PIPELINE_STAGE_VERTEX_SHADER_BIT

  • VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT

  • VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT

  • VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

  • VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT

  • VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

For the compute pipeline, the following stages occur in this order:

  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT

  • VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT

  • VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT

  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

For the transfer pipeline, the following stages occur in this order:

  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT

  • VK_PIPELINE_STAGE_TRANSFER_BIT

  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

For host operations, only one pipeline stage occurs, so no order is guaranteed:

  • VK_PIPELINE_STAGE_HOST_BIT

For conditional rendering operations, the pipeline stage where predicate read happens has no particular order relative to other stages.

  • VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT

For the command processing pipeline, the following stages occur in this order:

  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT

  • VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX

  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

6.1.3. Access Types

Memory in Vulkan can be accessed from = within shader invocations and via some fixed-function stages of the pipeline. The access type is a function of the descriptor ty= pe used, or how a fixed-function stage accesses memory. Each access type corresponds to a bit flag in VkAccessFla= gBits.

Some synchronization commands take sets of access types as parameters to define the access scopes of a memory dependency. If a synchronization command includes a source access mask, its first access scope only includes accesses via the access types specified in that mask. Similarly, if a synchronization command includes a destination access mask, its second access scope onl= y includes accesses via the access types specified in that mask.

Access types that can be set in an acc= ess mask include:

typedef enum VkAccessFlagBits {
    VK_ACCESS_INDIRECT_COMMAND_READ_BIT =3D 0x00000001<=
/span>,
    VK_ACCESS_INDEX_READ_BIT =3D 0x00000002,
    VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT =3D 0x00000004<=
/span>,
    VK_ACCESS_UNIFORM_READ_BIT =3D 0x00000008,
    VK_ACCESS_INPUT_ATTACHMENT_READ_BIT =3D 0x00000010<=
/span>,
    VK_ACCESS_SHADER_READ_BIT =3D 0x00000020,
    VK_ACCESS_SHADER_WRITE_BIT =3D 0x00000040,
    VK_ACCESS_COLOR_ATTACHMENT_READ_BIT =3D 0x00000080<=
/span>,
    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT =3D 0x00000100=
,
    VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT =3D 0x0=
0000200,
    VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT =3D 0x=
00000400,
    VK_ACCESS_TRANSFER_READ_BIT =3D 0x00000800,
    VK_ACCESS_TRANSFER_WRITE_BIT =3D 0x00001000,
    VK_ACCESS_HOST_READ_BIT =3D 0x00002000,
    VK_ACCESS_HOST_WRITE_BIT =3D 0x00004000,
    VK_ACCESS_MEMORY_READ_BIT =3D 0x00008000,
    VK_ACCESS_MEMORY_WRITE_BIT =3D 0x00010000,
    VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT =3D 0x=
00100000,
    VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX =3D 0x000200=
00,
    VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX =3D 0x00040=
000,
    VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT =3D 0x00080000,
} VkAccessFlagBits;

Certain access types are only performed by a subset of pipeline stages. Any synchronization command that takes both stage masks and access masks uses both to define the access scopes - only the specified access types performed by the specified sta= ges are included in the access scope. An application must not specify an access= flag in a synchronization command if it does not include a pipeline stage in the corresponding stage mask tha= t is able to perform accesses of that type. The following table lists, for each access flag, which pipeline stages can perform that type of access.

Table 4. Supported access types
Access flag Supported pipeline stages

VK_ACCESS_INDIRECT_COMMAND_READ_BIT

VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT

VK_ACCESS_INDEX_READ_BIT

VK_PIPELINE_STAGE_VERTEX_INPUT_BIT

VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT

VK_PIPELINE_STAGE_VERTEX_INPUT_BIT

VK_ACCESS_UNIFORM_READ_BIT

VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_TESS= ELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_EV= ALUATION_SHADER_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or VK_PIPELI= NE_STAGE_COMPUTE_SHADER_BIT

VK_ACCESS_INPUT_ATTACHMENT_READ_BIT

VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

VK_ACCESS_SHADER_READ_BIT

VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_TESS= ELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_EV= ALUATION_SHADER_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or VK_PIPELI= NE_STAGE_COMPUTE_SHADER_BIT

VK_ACCESS_SHADER_WRITE_BIT

VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_TESS= ELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_EV= ALUATION_SHADER_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or VK_PIPELI= NE_STAGE_COMPUTE_SHADER_BIT

VK_ACCESS_COLOR_ATTACHMENT_READ_BIT

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT

VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, or VK_PIPELINE_= STAGE_LATE_FRAGMENT_TESTS_BIT

VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT

VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, or VK_PIPELINE_= STAGE_LATE_FRAGMENT_TESTS_BIT

VK_ACCESS_TRANSFER_READ_BIT

VK_PIPELINE_STAGE_TRANSFER_BIT

VK_ACCESS_TRANSFER_WRITE_BIT

VK_PIPELINE_STAGE_TRANSFER_BIT

VK_ACCESS_HOST_READ_BIT

VK_PIPELINE_STAGE_HOST_BIT

VK_ACCESS_HOST_WRITE_BIT

VK_PIPELINE_STAGE_HOST_BIT

VK_ACCESS_MEMORY_READ_BIT

N/A=

VK_ACCESS_MEMORY_WRITE_BIT

N/A=

VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX

VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX

VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX

VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX

VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT

VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT

If a memory object does not have the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT property, then vkFlushMappedMemoryRanges must be called in order to guarantee that writes to the memory object from the host are made visible to the VK_ACCESS_HOST_WRITE_BIT access type, where it can be further made av= ailable to the device by synchronization commands. Similarly, vkInvalidateMappedMemoryRanges must be called to guarantee that writes which are visible to the VK_ACCESS_HOST_READ_BIT access type are made visible to host operations.

If the memory object does have the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT property flag, writes to = the memory object from the host are automatically made visible to the VK_ACCESS_HOST_WRITE_BIT access = type. Similarly, writes made visible to the VK_ACCESS_HOST_READ_BIT access type are automatically made visibl= e to the host.

Note

The vkQueueSubmit command automatically guarantees that host writes flushed to VK_ACCESS_HOST_WRITE_BIT are made available if they were f= lushed before the command executed, so in most cases an explicit memory barrier is not needed for this case. In the few circumstances where a submit does not occur between the host write and the device read access, writes can be made available by using an explicit memory barrier.

typedef VkFlags VkAccessFlags;

VkAccessFlags is a bitmask type for setting a mask of zero = or more VkAccessFlagBits.

6.1.4. Framebuffer Region De= pendencies

Pipeline stages that operate on, or with respect to, the framebuffer are collectively the framebuffer-space= pipeline stages. These stages are:

  • VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

  • VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT

  • VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT

  • VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

For these pipeline stages, an execution or memory dependency from the fi= rst set of operations to the second set can e= ither be a single framebuffer-global dependency, or split into multiple framebuf= fer-local dependencies. A dependency with non-framebuffer-space pipeline stages is neither framebuffer-global nor framebuffer-local.

A framebuffer region is a set of sample (x, y, layer, sample) c= oordinates that is a subset of the entire framebuffer.

Both synchronization scopes of = a framebuffer-local dependency include only the operations performed within corresponding framebuffer regions (as defined below). No ordering guarantees are made between different framebuffer regions for a framebuffer-local dependency.

Both synchronization scopes of = a framebuffer-global dependency include operations on all framebuffer-regions= .

If the first synchronization scope includes operations on pixels/fragmen= ts with N samples and the second synchronization scope includes operations on pixels/fragments with M samples, where N does not equal M, then a framebuffer region containing all samples at a given (x, y, layer) coordinate in the first synchronization scope corresponds to a region containing all samples at the same coordinate in the second synchronization scope. In other words, it is a pixel granularity dependency. If N equals M, then a framebuffer region containing a single (x, y, layer, sample) coordinate in the first synchronization scope corresponds to a region containing the same sample at the same coordinate in the second synchronization scope. In other words, it is a sample granularity dependency.

Note

Since fragment invocations are not specified to run in any particular groupings, the size of a framebuffer region is implementation-dependent, no= t known to the application, and must be ass= umed to be no larger than specified above.

Note

Practically, the pixel vs sample granularity dependency means that if an input attachment has a different number of samples than the pipeline=E2=80= =99s rasterizationSamples, then a fragment can access any sample in the input attachment=E2=80=99s pixel even if it only uses framebuffer-local dependencies. If the input attachment has the same number of samples, then the fragment can only access the covered samples in it= s input SampleMask (i.e. the fragment operations happen-after a framebuffer-local dependency for each sample the fragment covers). To access samples that are not covered, a framebuffer-global dependency is required.

If a synchronization command includes a dependencyFlags par= ameter, and specifies the VK_DEPENDENCY_BY_REGION_BIT flag, then it define= s framebuffer-local dependencies for the framebuffer-space pipeline stages in that synchronization command, for all framebuffer regions. If no dependencyFlags parameter is included, or the VK_DEPENDENCY_BY_REGION_BIT flag is not specified, then a framebuffer-global dependency is specified for those stages. The VK_DEPENDENCY_BY_REGION_BIT flag does not affect the depen= dencies between non-framebuffer-space pipeline stages, nor does it affect the dependencies between framebuffer-space and non-framebuffer-space pipeline stages.

Note

Framebuffer-local dependencies are more optimal for most architectures; particularly tile-based architectures - which can keep framebuffer-regions entirely in on-chip registers and thus avoid external bandwidth across such a dependency. Including a framebuffer-global dependency in your rendering will usually force all implementations to flush data to memory, or to a higher level cache, breaking any potential locality optimizations.

6.1.5. View-Local Depend= encies

In a render pass instance that has multiview enabled, dependencies can be either view-= local or view-global.

A view-local dependency only includes operations from a single source view from the source subpass in the first synchronization scope, and only includes operations from a single destination view from the destination subpass in the second synchronization scope. A view-global dependency includes all views in the view mask of the source and destination subpasses in the corresponding synchronization scopes.

If a synchronization command includes a dependencyFlags par= ameter and specifies the VK_DEPENDENCY_VIEW_LOCAL_BIT flag, then it defin= es view-local dependencies for that synchronization command, for all views. If no dependencyFlags parameter is included or the VK_DEPENDENCY_VIEW_LOCAL_BIT flag is not specified, then a vie= w-global dependency is specified.

6.1.6. Device-Local De= pendencies

Dependencies can be either device-loca= l or non-device-local. A device-local dependency acts as multiple separate dependencies, one for each physical device that executes the synchronization command, where each dependency only includes operations from that physical device in both synchronization scopes. A non-device-local dependency is a single dependency where both synchronization scopes include operations from all physical devices that participate in the synchronization command. For subpass dependencies, all physical devices in the VkDeviceGroupRenderPassBeginInfo::deviceMask participate in the dependency, and for pipeline barriers all physical devices that are set in the command buffer=E2=80=99s current device mask participate in the depende= ncy.

If a synchronization command includes a dependencyFlags par= ameter and specifies the VK_DEPENDENCY_DEVICE_GROUP_BIT flag, then it def= ines a non-device-local dependency for that synchronization command. If no dependencyFlags parameter is included or the VK_DEPENDENCY_DEVICE_GROUP_BIT flag is not specified, then it = defines device-local dependencies for that synchronization command, for all participating physical devices.

Semaphore and event dependencies are device-local and only execute on th= e one physical device that performs the dependency.

6.2. Implicit Synchronization Guarantee= s

A small number of implicit ordering guarantees are provided by Vulkan, ensuring that the order in which commands are submitted is meaningful, and avoiding unnecessary complexity in common operations.

Submission order is a fundamental ordering in Vulkan, giving me= aning to the order in which action and synchronization commands are recorded and submitted to a single queue. Explicit and implicit ordering guarantees between commands in Vulkan all work on the premise that this ordering is meaningful. This order does not itself define any execution or memory dependencies; synchronization commands and other orderings within the API use this ordering to define their scopes.

Submission order for any given set of commands is based on the order in which they were recorded to command buffers and then submitted. This order is determined as follows:

  1. The initial order is determined by the order in which vkQueueSubmit commands are executed on the host, for a s= ingle queue, from first to last.

  2. The order in which VkSubmitInfo structures are specifi= ed in the pSubmits parameter of vkQueueSubmit, from l= owest index to highest.

  3. The order in which command buffers are specified in the pCommandBuffers member of VkSubmitInfo, from= lowest index to highest.

  4. The order in which commands were recorded to a command buffer on the host, from first to last:

    • For commands recorded outside a render pass, this includes all other commands recorded outside a render pass, including vkCmdBeginRenderPass and vkCm= dEndRenderPass commands; it does not directly include commands inside a render pass.

    • For commands recorded inside a render pass, this includes all other commands recorded inside the same subpass, including the vkCmdBeginRenderPass and vkCm= dEndRenderPass commands that delimit the same render pass instance; it does not include commands recorded to other subpasses.

Action and synchronization commands recorded to a command buffer execute the VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT pipeline stage in submission order - forming an implici= t execution dependency between this stage in each command.

State commands do not exe= cute any operations on the device, instead they set the state of the command buffer when they execute on the host, in the order that they are recorded. Action commands consume the current state of the command buffer when they are recorded, and will execut= e state changes on the device as required to match the recorded state.

Execution of pipeline stages within a given command also has a loose ordering, dependent only on a singl= e command.

6.3. Fences

Fences are a synchronization primitive that can= be used to insert a dependency from a queue to the host. Fences have two states - signaled and unsignaled. A fence can be signaled as part of the ex= ecution of a queue submission command. Fences can be unsignaled on the host with= vkResetFences. Fences can be waited on by the host with = the vkWaitForFences command, and the current state can be queried with= vkGetFenceStatus.

As with most objects in Vulkan, fences are an interface to internal data which is typically opaque to applications. This internal data is referred to as a fence=E2=80=99s payload.

However, in order to enable communication with agents outside of the cur= rent device, it is necessary to be able to export that payload to a commonly understood format, and subsequently import from that format as well.

The internal data of a fence may inclu= de a reference to any resources and pending work associated with signal or unsignal operations performed on tha= t fence object. Mechanisms to import and export that internal data to and from fences are provided below. These mechanisms indirectly enable applications to share fence state betwee= n two or more fences and other synchronization primitives across process and API boundaries.

Fences are represented by VkFence handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkFence)

To create a fence, call:

VkResult vkCreateF=
ence(
    VkDevice                                    device,
    const VkFenceCreateInfo*              =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkFence*                                    pFence);
  • device is the logical device that creates the fence.

  • pCreateInfo is a pointer to an instance of the VkFenceCreateInfo structure which contains information about h= ow the fence is to be created.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pFence points to a handle in which the resulting fence obje= ct is returned.

Valid Usage (Implicit)
  • device <= strong class=3D"purple">must be a valid VkDevice hand= le

  • pCreateInf= o must be a valid pointer to a val= id VkFenceCreateInfo structure

  • If pAllocat= or is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • pFence <= strong class=3D"purple">must be a valid pointer to a VkFence= handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkFenceCreateInfo structure is defined as:

typedef struct VkFenceCreateInf=
o {
    VkStructureType       sType;
    const void*           pNext;
    VkFenceCreateFlags    flags;
} VkFenceCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkFenceCreateF= lagBits specifying the initial state and behavior of the fence.

Valid Usage (Implicit)
typedef enum VkFenceCreateFlagB=
its {
    VK_FENCE_CREATE_SIGNALED_BIT =3D 0x00000001,
} VkFenceCreateFlagBits;
  • VK_FENCE_CREATE_SIGNALED_BIT specifies that the fence objec= t is created in the signaled state. Otherwise, it is created in the unsignaled state.

typedef VkFlags VkFenceCreateFlags;

VkFenceCreateFlags is a bitmask type for setting a mask of = zero or more VkFenceCreateFlagBits.

To create a fence whose payload can be= exported to external handles, add the VkExportFenceCreateInfo structure to the <= code>pNext chain of the VkFenceCreateInfo structure. The VkExportFenceCreateInfo structure is defined as:

typedef struct VkExportFenceCre=
ateInfo {
    VkStructureType                   sType;
    const void*                       pNext;
    VkExternalFenceHandleTypeFlags    handleTypes;
} VkExportFenceCreateInfo;

or the equivalent

typedef VkExportFenceCreateInfo VkExportFenceCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleTypes is a bitmask of VkExternalFenceHandleTypeFlagBits sp= ecifying one or more fence handle types the application can export f= rom the resulting fence. The application can request multiple hand= le types for the same fence.

Valid Usage
Valid Usage (Implicit)

To specify additional attributes of NT handles exported from a fence, ad= d the VkExportFenceWin32HandleInfoKHR st= ructure to the pNext chain of the VkFenceCreateInfo structure. The VkExportFenceWin32HandleInfoKHR structure is defined as:

typedef struct VkExportFenceWin=
32HandleInfoKHR {
    VkStructureType               sType;
    const void*                   pNext;
    const SECURITY_ATTRIBUTES*    pAttribu=
tes;
    DWORD                         dwAccess;
    LPCWSTR                       name;
} VkExportFenceWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • pAttributes is a pointer to a Windows SECURITY_ATTRIB= UTES structure specifying security attributes of the handle.

  • dwAccess is a DWORD specifying access rights o= f the handle.

  • name is a NULL-terminated UTF-16 string to associate with t= he underlying synchronization primitive referenced by NT handles exported from the created fence.

If this structure is not present, or if pAttributes is set = to NULL, default security descriptor values will be used, and child processes create= d by the application will not inherit the handle, as described in the MSDN documentation for =E2=80=9CSynchronization Object Security and Access Right= s=E2=80=9D1. Further, if the structure is not present, the access rights will be

DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRIT= E

for handles of the following types:

VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT

Valid Usage
  • If VkExportFenceCreateInfo::handleTypes<= /code> does not include VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT, VkExportFenceWin32HandleInfoKHR must<= /strong> not be in the pNext chain of VkFenceCreateInfo.

Valid Usage (Implicit)

To export a Windows handle representing the state of a fence, call:

VkResult vkGetFenc=
eWin32HandleKHR(
    VkDevice                                    device,
    const VkFenceGetWin32HandleInfoKHR*   =
      pGetWin32HandleInfo,
    HANDLE*                                     pHandle);

For handle types defined as NT handles, the handles returned by vkGetFenceWin32HandleKHR are owned by the application. To avoid leaking resources, the application must release ownership of them using the CloseHandle system call when they are no longer need= ed.

Exporting a Windows handle from a fence may have side effects depending on the transference of the specified handle type, as described in Importing Fence Payloads.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkFenceGetWin32HandleInfoKHR structure is defined as:

typedef struct VkFenceGetWin32H=
andleInfoKHR {
    VkStructureType                      sType;
    const void*                          pNext;
    VkFence                              fence;
    VkExternalFenceHandleTypeFlagBits    handleType;
} VkFenceGetWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • fence is the fence from which state will be exported.

  • handleType is the type of handle requested.

The properties of the handle returned depend on the value of handleType. See VkExternalFenceHandleTypeFlagBits for a description of the properties of the defined external fence handle types.

Valid Usage
  • handleType must have been in= cluded in VkExportFenceCreateInfo::handleTypes when the fence=E2=80=99s current payload was created.

  • If handleType is defined as an NT handle, vkGetFenceWin32HandleKHR must be called no more than once for each valid unique combination of fence and handleType.

  • fence must not currently hav= e its payload replaced by an imported payload as described below in Importing Fence Payloads unless that imported payload=E2=80=99s handle type was included in VkExternalFenceProperties::exportFromI= mportedHandleTypes for handleType.

  • If handleType refers to a handle type with copy payload transference semantics, fence must be signaled, or have an associated fence signal operation pending execution.

  • handleType must be defined a= s an NT handle or a global share handle.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_F= ENCE_GET_WIN32_HANDLE_INFO_KHR

  • pNext= must be NULL

  • f= ence must be a valid VkFence= handle

  • handleType must be a valid VkExternalFenceHandleTypeFlagBits value=

To export a POSIX file descriptor representing the payload of a fence, c= all:

VkResult vkGetFenc=
eFdKHR(
    VkDevice                                    device,
    const VkFenceGetFdInfoKHR*            =
      pGetFdInfo,
    int*                            =
            pFd);
  • device is the logical device that created the fence being exported.

  • pGetFdInfo is a pointer to an instance of the VkFenceGetFdInfoKHR structure containing parameter= s of the export operation.

  • pFd will return the file descriptor representing the fence payload.

Each call to vkGetFenceFdKHR must<= /strong> create a new file descriptor and transfer ownership of it to the application. To avoid leaking resources, the application must release ownership of the file descriptor when it is no longer needed.

Note

Ownership can be released in many ways. For example, the application can call close() on the file desc= riptor, or transfer ownership back to Vulkan by using the file descriptor to import a fence payload.

If pGetFdInfo->handleType is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT and the fence is sig= naled at the time vkGetFenceFdKHR is called, pFd may return the value -1 instead of a valid file descriptor.

Where supported by the operating system, the implementation must set the file descriptor to be closed automatically when an execve syst= em call is made.

Exporting a file descriptor from a fence may have side effects depending on the transference of the specified handle type, as described in Importing Fence State.

Valid Usage (Implicit)
  • device= must be a valid VkDevice ha= ndle

  • pGetFdInf= o must be a valid pointer to a val= id VkFenceGetFdInfoKHR structure

  • pFd must be a valid pointer to a int = value

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkFenceGetFdInfoKHR structure is defined as:

typedef struct VkFenceGetFdInfo=
KHR {
    VkStructureType                      sType;
    const void*                          pNext;
    VkFence                              fence;
    VkExternalFenceHandleTypeFlagBits    handleType;
} VkFenceGetFdInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • fence is the fence from which state will be exported.

  • handleType is the type of handle requested.

The properties of the file descriptor returned depend on the value of handleType. See VkExternalFenceHandleTypeFlagBits for a description of the properties of the defined external fence handle types.

Valid Usage
  • handleType must have been in= cluded in VkExportFenceCreateInfo::handleTypes when fence=E2=80=99s current payload was created.

  • If handleType refers to a handle type with copy payload transference semantics, fence must be signaled, or have an associated fence signal operation pending execution.

  • fence must not currently hav= e its payload replaced by an imported payload as described below in Importing Fence Payloads unless that imported payload=E2=80=99s handle type was included in VkExternalFenceProperties::exportFromI= mportedHandleTypes for handleType.

  • handleType must be defined a= s a POSIX file descriptor handle.

Valid Usage (Implicit)
  • sType <= strong class=3D"purple">must be VK_STRUCTURE_TYPE_FENCE_GET_= FD_INFO_KHR

  • pNext <= strong class=3D"purple">must be NULL

  • fence must be a valid VkFence h= andle

  • handl= eType must be a valid VkExternalFenceHandleTypeFlagBits value

To destroy a fence, call:

void vkDestroyFence(
    VkDevice                                    device,
    VkFence                                     fence,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the fence.

  • fence is the handle of the fence to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All queue submission commands that refer to fence must have completed= execution

  • If VkAllocationCallbacks were provided when fence= was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when fence was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device = must be a valid VkDevice han= dle

  • If fence= is not VK_NULL_HANDLE, fence must be a valid VkFence handle

  • If pAlloca= tor is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • If fence is= a valid handle, it must have been create= d, allocated, or retrieved from device

Host Synchronization
  • Host access to fence must= be externally synchronized

To query the status of a fence from the host, call:

VkResult vkGetFenc=
eStatus(
    VkDevice                                    device,
    VkFence                                     fence);
  • device is the logical device that owns the fence.

  • fence is the handle of the fence to query.

Upon success, vkGetFenceStatus returns the status of the fe= nce object, with the following return codes:

Table 5. Fence Object Status Codes
Status Meaning

VK_SUCCESS

The= fence specified by fence is signaled.

VK_NOT_READY

The= fence specified by fence is unsignaled.

VK_ERROR_DEVICE_LOST

The= device has been lost. See Lost Device.

=

If a queue submission command is pending execution, then the value returned by this command may immediately be out of date.

Valid Usage (Implicit)
  • device must be a valid VkDevice h= andle

  • fence = must be a valid VkFence hand= le

  • fence must have been created, allocated, or retrie= ved from device

Return Codes
Success
  • VK_SUCCESS

  • VK_NOT_READY

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

To set the state of fences to unsignaled from the host, call:

VkResult vkResetFe=
nces(
    VkDevice                                    device,
    uint32_t                                    fenceCount,
    const VkFence*                        =
      pFences);
  • device is the logical device that owns the fences.

  • fenceCount is the number of fences to reset.

  • pFences is a pointer to an array of fence handles to reset.=

If any member of pFences currently has its payload imported with temporary permanence, that fence=E2=80=99s prior permanent payload is first restored. The remaining operations described therefore operate on the restored payload.

When vkResetFences is executed on the host, it define= s a fence unsignal operation for each fence, which resets the fence to the unsig= naled state.

If any member of pFences is already in the unsignaled state= when vkResetFences is executed, then vkResetFe= nces has no effect on that fence.

Valid Usage
  • Each element of pFences must= not be currently associated with any queue command that has not yet completed execution on that queue

Valid Usage (Implicit)
  • device <= strong class=3D"purple">must be a valid VkDevice hand= le

  • pFences= must be a valid pointer to an array of <= code>fenceCount valid VkFence handles

  • fenceCoun= t must be greater than 0

  • Each element of p= Fences must have been created, all= ocated, or retrieved from device

Host Synchronization
  • Host access to each member of pFences must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

When a fence is submitted to a queue as part of a queue submission command, it defines a memory dependency on the batches that were submitted as part of that command, and defines a fence signal operation which sets the fence to the signa= led state.

The first synchronization scope includes every batch submitted in the same queue submission command. Fence signal operations that are defined by vkQueueSubmit additionally include in the first synchronization scope all commands that occur earlier in submission order.

The first access scope includes all memory access performed by the device.

The second access scope = is empty.

To wait for one or more fences to enter the signaled state on the host, call:

VkResult vkWaitFor=
Fences(
    VkDevice                                    device,
    uint32_t                                    fenceCount,
    const VkFence*                        =
      pFences,
    VkBool32                                    waitAll,
    uint64_t                                    timeout);
  • device is the logical device that owns the fences.

  • fenceCount is the number of fences to wait on.

  • pFences is a pointer to an array of fenceCount= fence handles.

  • waitAll is the condition that must= be satisfied to successfully unblock the wait. If waitAll is VK_TRUE, then the condition is that= all fences in pFences are signaled. Otherwise, the condition is that at least one fence in pFences= is signaled.

  • timeout is the timeout period in units of nanoseconds. timeout is adjusted to the closest value allowed by the implementation-dependent timeout accuracy, which m= ay be substantially longer than one nanosecond, and may be lo= nger than the requested period.

If the condition is satisfied when vkWaitForFences is calle= d, then vkWaitForFences returns immediately. If the condition is not satisfied at the time vkWaitForFences = is called, then vkWaitForFences will block and wait up to t= imeout nanoseconds for the condition to become satisfied.

If timeout is zero, then vkWaitForFences does = not wait, but simply returns the current state of the fences. VK_TIMEOUT will be returned in this case if the condition is n= ot satisfied, even though no actual wait was performed.

If the specified timeout period expires before the condition is satisfie= d, vkWaitForFences returns VK_TIMEOUT. If the condition is satisfied before timeout nanoseconds has e= xpired, vkWaitForFences returns VK_SUCCESS.

If device loss occurs (see Lost Device) b= efore the timeout has expired, vkWaitForFences must return in finite time with either VK_SUCCESS or VK_ERROR_DEVICE_LOST.

Note

While we guarantee that vkWaitForFences must return in finite time, no guarantees are made that it returns immediately upon device loss. However, the client can reasonably expect that the delay will be on the order of seconds and that calling vkWaitForFences will not res= ult in a permanently (or seemingly permanently) dead process.

Valid Usage (Implicit)
  • device= must be a valid VkDevice ha= ndle

  • pFences must be a valid pointer to an array of= fenceCount valid VkFence handles

  • fenceCo= unt must be greater than 0

  • Each element of pFences must have been created, a= llocated, or retrieved from device

Return Codes
Success
  • VK_SUCCESS

  • VK_TIMEOUT

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

An execution dependency is defined by waiting for a fence to become signaled, either via vkWaitForFences or by polling on vkGetFenceStatus.

The first synchronization scope includes only the fence signal operation.

The second synchronization scope includes the host operations of vkWaitForFences or vkGetFenceStatus indicating that the fence has become= signaled.

Note

Signaling a fence and waiting on the host does not guarantee that the results of memory accesses will be visible to the host, as the access scope of a memory dependency defined by a fence only includes device access. A memory barrier or other memory dependency must be used to guarantee this= . See the description of host access types for more information.

6.3.1. Alternate Methods to = Signal Fences

Besides submitting a fence to a queue as part of a queue submission command, a fence may also be signaled when a particular event occurs on a device or display.

To create a fence that will be signaled when an event occurs on a device= , call:

VkResult vkRegiste=
rDeviceEventEXT(
    VkDevice                                    device,
    const VkDeviceEventInfoEXT*           =
      pDeviceEventInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkFence*                                    pFence);
  • device is a logical device on which the event may occur.

  • pDeviceEventInfo is a pointer to an instance of the VkDeviceEventInfoEXT structure describing the eve= nt of interest to the application.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pFence points to a handle in which the resulting fence obje= ct is returned.

Valid Usage (Implicit)
  • devi= ce must be a valid VkDevice<= /code> handle

  • = pDeviceEventInfo must be a v= alid pointer to a valid VkDeviceEventInfoEXT structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAl= locationCallbacks structure

  • pFen= ce must be a valid pointer to a VkFence handle

Return Codes
Success
  • VK_SUCCESS

The VkDeviceEventInfoEXT structure is defined as:

typedef struct VkDeviceEventInf=
oEXT {
    VkStructureType         sType;
    const void*             pNext;
    VkDeviceEventTypeEXT    deviceEvent;
} VkDeviceEventInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • device is a VkDeviceEventTypeEXT = value specifying when the fence will be signaled.

Valid Usage (Implicit)
  • sType = must be VK_STRUCTURE_TYPE_DEVICE_EV= ENT_INFO_EXT

  • pNext = must be NULL

  • dev= iceEvent must be a valid VkDeviceEventTypeEXT value

Possible values of VkDeviceEventInfoEXT::device, specifying when a fence will be signaled, are:

typedef enum VkDeviceEventTypeE=
XT {
    VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT =3D 0<=
/span>,
} VkDeviceEventTypeEXT;
  • VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT specifies that the= fence is signaled when a display is plugged into or unplugged from the specified device. Applications can use this notification to= determine when they need to re-enumerate the available displays on a device.

To create a fence that will be signaled when an event occurs on a VkDisplayKHR object, call:

VkResult vkRegiste=
rDisplayEventEXT(
    VkDevice                                    device,
    VkDisplayKHR                                display,
    const VkDisplayEventInfoEXT*          =
      pDisplayEventInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkFence*                                    pFence);
  • device is a logical device associated with display

  • display is the display on which the event may occur.

  • pDisplayEventInfo is a pointer to an instance of the VkDisplayEventInfoEXT structure describing the e= vent of interest to the application.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pFence points to a handle in which the resulting fence obje= ct is returned.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

The VkDisplayEventInfoEXT structure is defined as:

typedef struct VkDisplayEventIn=
foEXT {
    VkStructureType          sType;
    const void*              pNext;
    VkDisplayEventTypeEXT    displayEvent;
} VkDisplayEventInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • displayEvent is a VkDisplayEventType= EXT specifying when the fence will be signaled.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_DISPLAY_= EVENT_INFO_EXT

  • pNext= must be NULL

  • d= isplayEvent must be a valid VkDisplayEventTypeEXT value

Possible values of VkDisplayEventInfoEXT::displayEvent, specifying when a fence will be signaled, are:

typedef enum VkDisplayEventType=
EXT {
    VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT =3D 0=
,
} VkDisplayEventTypeEXT;
  • VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT specifies that th= e fence is signaled when the first pixel of the next display refresh cycle leaves the display engine for the display.

6.3.2. Importing Fence Payloads=

Applications can import a fence payloa= d into an existing fence using an external fence handle. The effects of the import operation will be either temporary or permanent, as specified by the application. If the import is temporary, the fence will be restored to its perm= anent state the next time that fence is passed to vkResetFences.

Note

Restoring a fence to its prior permanent payload is a distinct operation from resetting a fence payload. See vkResetFences for more detail.

Performing a subsequent temporary import on a fence before resetting it = has no effect on this requirement; the next unsignal of the fence must still restore its last permanent state. A permanent payload import behaves as if the target fence was destroyed, an= d a new fence was created with the same handle but the imported payload. Because importing a fence payload temporarily or permanently detaches the existing payload from a fence, similar usage restrictions to those applied to vkDestroyFence are applied to any command that imports a fe= nce payload. Which of these import types is used is referred to as the import operation= =E2=80=99s permanence. Each handle type supports either one or both types of permanence.

The implementation must perform the im= port operation by either referencing or copying the payload referred to by the specified external fence handle, depending on the handle=E2=80=99s type. The import method used is referred to as the handle type=E2=80=99s tran= sference. When using handle types with reference transference, importing a payload to a fence adds the fence to the set of all fences sharing that payload. This set includes the fence from which the payload was exported. Fence signaling, waiting, and resetting operations performed on any fence i= n the set must behave as if the set were a = single fence. Importing a payload using handle types with copy transference creates a duplicate copy of the payload at the time of import, but makes no further reference to it. Fence signaling, waiting, and resetting operations performed on the target of copy imports must not affect any other= fence or payload.

Export operations have the same transference as the specified handle typ= e=E2=80=99s import operations. Additionally, exporting a fence payload to a handle with copy transference has the same side effects on the source fence=E2=80=99s payload as executin= g a fence reset operation. If the fence was using a temporarily imported payload, the fence=E2=80=99s = prior permanent payload will be restored.

Note

The tables Handle Types Supported by VkImportFenceWin32HandleInfoKHR and Handle Types Supported by VkImportFenceFdInfoKHR define the permanence and transference of each handle type.

External synchronization allows implementations to modify an object=E2=80=99s internal state, i.e. payload,= without internal synchronization. However, for fences sharing a payload across processes, satisfying the external synchronization requirements of VkFence parameters as= if all fences in the set were the same object is sometimes infeasible. Satisfying valid usage constraints on the state of a fence would similarly require impractical coordination or levels of trust between processes. Therefore, these constraints only apply to a specific fence handle, not to its payload. For distinct fence objects which share a payload:

  • If multiple commands which queue a signal operation, or which unsignal a fence, are called concurrently, behavior will be as if the commands were called in an arbitrary sequential order.

  • If a queue submission command is called with a fence that is sharing a payload, and the payload is already associated with another queue command that has not yet completed execution, either one or both of the commands will cause the fence to become signaled when they complete execution.

  • If a fence payload is reset while it is associated with a queue command that has not yet completed execution, the payload will become unsignaled, but may become signaled again when the co= mmand completes execution.

  • In the preceding cases, any of the devices associated with the fences sharing the payload may be lost, or any o= f the queue submission or fence reset commands may return VK_ERROR_= INITIALIZATION_FAILED.

Other than these non-deterministic results, behavior is well defined. In particular:

  • The implementation must not crash or e= nter an internally inconsistent state where future valid Vulkan commands might cause undefined results,

  • Timeouts on future wait commands on fences sharing the payload must be effective.

Note

These rules allow processes to synchronize access to shared memory witho= ut trusting each other. However, such processes must still be cautious not to use the shared fence for more than synchronizing access to the shared memory. For example, a process should not use a fence with shared payload to tell when commands it submitted to a queue have completed and objects used by those commands may be destroyed, since the other process can accidentally o= r maliciously cause the fence to signal before the commands actually complete= .

When a fence is using an imported payload, its VkExportFenceCreateInfo::handleTypes value is that specified when creating the fence from which the payload was exported, rather than that specified when creating the fence. Additionally, VkExternalFenceProperties::exp= ortFromImportedHandleTypes restricts which handle types can be expor= ted from such a fence based on the specific handle type used to import the current payload. Passing a fence to vkAcquireNextImageKHR is equi= valent to temporarily importing a fence payload to that fence.

When importing a fence payload, it is the responsibility of the applicat= ion to ensure the external handles meet all valid usage requirements. However, implementations must perform suf= ficient validation of external handles to ensure that the operation results in a valid fence which will no= t cause program termination, device loss, queue stalls, host thread stalls, o= r corruption of other resources when used as allowed according to its import parameters. If the external handle provided does not meet these requirements, the implementation must fail the fence payloa= d import operation with the error code VK_ERROR_INVALID_EXTERNAL_HANDLE.

To import a fence payload from a Windows handle, call:

VkResult vkImportF=
enceWin32HandleKHR(
    VkDevice                                    device,
    const VkImportFenceWin32HandleInfoKHR*=
      pImportFenceWin32HandleInfo);
  • device is the logical device that created the fence.

  • pImportFenceWin32HandleInfo points to a VkImportFenceWin32HandleInfoKHR struct= ure specifying the fence and import parameters.

Importing a fence payload from Windows handles does not transfer ownersh= ip of the handle to the Vulkan implementation. For handle types defined as NT handles, the application must release ownership using the CloseHandle system call when the handle is= no longer needed.

Applications can import the same fence= payload into multiple instances of Vulkan, into the same instance from which it was exported, and multiple times into a given Vulkan instance.

Valid Usage (Implicit)
  • d= evice must be a valid VkDevi= ce handle

  • pImportFenceWin32HandleInfo must be a valid pointer to a valid VkImportFenceWin32Ha= ndleInfoKHR structure

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_INVALID_EXTERNAL_HANDLE

The VkImportFenceWin32HandleInfoKHR structure is defined as= :

typedef struct VkImportFenceWin=
32HandleInfoKHR {
    VkStructureType                      sType;
    const void*                          pNext;
    VkFence                              fence;
    VkFenceImportFlags                   flags;
    VkExternalFenceHandleTypeFlagBits    handleType;
    HANDLE                               handle;
    LPCWSTR                              name;
} VkImportFenceWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • fence is the fence into which the state will be imported.

  • flags is a bitmask of VkFenceImportF= lagBits specifying additional parameters for the fence payload import operation.

  • handleType specifies the type of handle.

  • handle is the external handle to import, or NULL.

  • name is the NULL-terminated UTF-16 string naming the underl= ying synchronization primitive to import, or NULL.

The handle types supported by handleType are:

Table 6. Handle Types Supported by VkImportFenceWi= n32HandleInfoKHR
Handle Type Transference Permanence Supported

VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT

Ref= erence

Tem= porary,Permanent

VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT

Ref= erence

Tem= porary,Permanent

Valid Usage
  • handleType must be a value i= ncluded in the Handle Types Supported by VkImportFenceWin32HandleInfoKHR table.

  • If handleType is not VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT, name must be NULL.

  • If handleType is not 0 and handle is= NULL, name must name a valid synchronization primiti= ve of the type specified by handleType.

  • If handleType is not 0 and name is <= code>NULL, handle must be a valid handle of the type specif= ied by handleType.

  • If handle is not NULL, name must be = NULL.

  • If handle is not NULL, it must obey any requirements listed for handleType in exter= nal fence handle types compatibility.

  • If name is not NULL, it = must obey any requirements listed for handleType in exter= nal fence handle types compatibility.

Valid Usage (Implicit)
  • sT= ype must be VK_STRUCTURE_TYP= E_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR

  • pN= ext must be NULL

  • fence must be a valid VkFe= nce handle

  • flags must be a valid combinatio= n of VkFenceImportFlagBits values

  • = If handleType is not 0, handleType = must be a valid VkExternalFenceHandleTypeFlagBits value

Host Synchronization
  • Host access to fence must= be externally synchronized

To import a fence payload from a POSIX file descriptor, call:

VkResult vkImportF=
enceFdKHR(
    VkDevice                                    device,
    const VkImportFenceFdInfoKHR*         =
      pImportFenceFdInfo);
  • device is the logical device that created the fence.

  • pImportFenceFdInfo points to a VkIm= portFenceFdInfoKHR structure specifying the fence and import parameters.

Importing a fence payload from a file descriptor transfers ownership of = the file descriptor from the application to the Vulkan implementation. The application must not perform any oper= ations on the file descriptor after a successful import.

Applications can import the same fence= payload into multiple instances of Vulkan, into the same instance from which it was exported, and multiple times into a given Vulkan instance.

Valid Usage
  • fence must not be associated= with any queue command that has not yet completed execution on that queue

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • pImportFenceFdInfo must be a val= id pointer to a valid VkImportFenceFdInfoKHR structure

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_INVALID_EXTERNAL_HANDLE

The VkImportFenceFdInfoKHR structure is defined as:

typedef struct VkImportFenceFdI=
nfoKHR {
    VkStructureType                      sType;
    const void*                          pNext;
    VkFence                              fence;
    VkFenceImportFlags                   flags;
    VkExternalFenceHandleTypeFlagBits    handleType;
    int                             =
     fd;
} VkImportFenceFdInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • fence is the fence into which the payload will be imported.=

  • flags is a bitmask of VkFenceImportF= lagBits specifying additional parameters for the fence payload import operation.

  • handleType specifies the type of fd.

  • fd is the external handle to import.

The handle types supported by handleType are:

Table 7. Handle Types Supported by VkImportFenceFd= InfoKHR
Handle Type Transference Permanence Supported

VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT

Ref= erence

Tem= porary,Permanent

VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT

Cop= y

Tem= porary

Valid Usage

If handleType is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_F= D_BIT, the special value -1 for fd is treated like a valid s= ync file descriptor referring to an object that has already signaled. The import operation will succeed and the VkFence will have a temporarily imported payload as if a valid file descriptor had been provided.

Note

This special behavior for importing an invalid sync file descriptor allo= ws easier interoperability with other system APIs which use the convention tha= t an invalid sync file descriptor represents work that has already completed and does not need to be waited for. It is consistent with the option for implementations to return a -1 file descriptor when exporting a VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT= from a VkFence which is signaled.

Valid Usage (Implicit)
Host Synchronization
  • Host access to fence must= be externally synchronized

Bits which can be set in VkImportFenceWin32HandleInfoKHR::flags and VkImportFenceFdInfoKHR::flags specifying additional parameters of a fence import operation are:

typedef enum VkFenceImportFlagB=
its {
    VK_FENCE_IMPORT_TEMPORARY_BIT =3D 0x00000001=
,
    VK_FENCE_IMPORT_TEMPORARY_BIT_KHR =3D VK_FENCE_IMPORT_TEMPORARY_BIT,
} VkFenceImportFlagBits;

or the equivalent

typedef VkFenceImportFlagBits VkFenceImportFlagBitsKHR;=
  • VK_FENCE_IMPORT_TEMPORARY_BIT specifies that the fence payl= oad will be imported only temporarily, as described in Importing Fence Payloads, regardless of the permanence of handleType.

typedef VkFlags VkFenceImportFlags;

or the equivalent

typedef VkFenceImportFlags VkFenceImportFlagsKHR;

VkFenceImportFlags is a bitmask type for setting a mask of = zero or more VkFenceImportFlagBits.

6.4. Semaphores

Semaphores are a synchronization primitive that can be used to insert a dependency between batches submitted to queues. Semaphores have two states - signaled and unsignaled. The state of a semaphore can be signaled = after execution of a batch of commands is completed. A batch can wait for a semaphore to becom= e signaled before it begins execution, and the semaphore is also unsignaled before the batch begins execution.

As with most objects in Vulkan, semaphores are an interface to internal = data which is typically opaque to applications. This internal data is referred to as a semaphore=E2=80=99s payload= .

However, in order to enable communication with agents outside of the cur= rent device, it is necessary to be able to export that payload to a commonly understood format, and subsequently import from that format as well.

The internal data of a semaphore may i= nclude a reference to any resources and pending work associated with signal or unsignal operations performed on that semaphore object. Mechanisms to import and export that internal data to and from semaphores are provided below. These mechanisms indirectly enable applications to share semaphore state between two or more semaphores and other synchronization primitives across process and API boundaries.

Semaphores are represented by VkSemaphore handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkSemaphore)

To create a semaphore, call:

VkResult vkCreateS=
emaphore(
    VkDevice                                    device,
    const VkSemaphoreCreateInfo*          =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSemaphore*                                pSemaphore);
  • device is the logical device that creates the semaphore.

  • pCreateInfo is a pointer to an instance of the VkSemaphoreCreateInfo structure which contains information abo= ut how the semaphore is to be created.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pSemaphore points to a handle in which the resulting semaph= ore object is returned.

When created, the semaphore is in the unsignaled state.

Valid Usage (Implicit)
  • device must be a valid VkDevice = handle

  • pCreat= eInfo must be a valid pointer to a= valid VkSemaphoreCreateInfo structure

  • If pAll= ocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocatio= nCallbacks structure

  • pSemaph= ore must be a valid pointer to a <= code>VkSemaphore handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkSemaphoreCreateInfo structure is defined as:

typedef struct VkSemaphoreCreat=
eInfo {
    VkStructureType           sType;
    const void*               pNext;
    VkSemaphoreCreateFlags    flags;
} VkSemaphoreCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_SEMAPHOR= E_CREATE_INFO

  • Each pNext member of any structure (including this one) in the pNext chain must be either NULL = or a pointer to a valid instance of VkExportSe= maphoreCreateInfo or VkExportSemap= horeWin32HandleInfoKHR

  • Each sType<= /code> member in the pNext chain must= be unique

  • flags<= /code> must be 0

typedef VkFlags VkSemaphoreCreateFlags;

VkSemaphoreCreateFlags is a bitmask type for setting a mask= , but is currently reserved for future use.

To create a semaphore whose payload can be exported to external handles, add the VkExportSemaphoreCreateInfo struct= ure to the pNext chain of the VkSemaphoreCreateInfo structure. The VkExportSemaphoreCreateInfo structure is defined as:

typedef struct VkExportSemaphor=
eCreateInfo {
    VkStructureType                       sType;
    const void*                           pNext;
    VkExternalSemaphoreHandleTypeFlags    handleTypes;
} VkExportSemaphoreCreateInfo;

or the equivalent

typedef VkExportSemaphoreCreateInfo VkExportSemaphoreCreateInf=
oKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleTypes is a bitmask of VkExternalSemaphoreHandleTypeFlagBit= s specifying one or more semaphore handle types the application can export from the resulting semaphore. The application can request multiple hand= le types for the same semaphore.

Valid Usage
Valid Usage (Implicit)

To specify additional attributes of NT handles exported from a semaphore= , add the VkExportSemaphoreWin32HandleInfoKHR structure to the pNext chain of the VkSemaphoreCreateInf= o structure. The VkExportSemaphoreWin32HandleInfoKHR structure is defined a= s:

typedef struct VkExportSemaphor=
eWin32HandleInfoKHR {
    VkStructureType               sType;
    const void*                   pNext;
    const SECURITY_ATTRIBUTES*    pAttribu=
tes;
    DWORD                         dwAccess;
    LPCWSTR                       name;
} VkExportSemaphoreWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • pAttributes is a pointer to a Windows SECURITY_ATTRIB= UTES structure specifying security attributes of the handle.

  • dwAccess is a DWORD specifying access rights o= f the handle.

  • name is a NULL-terminated UTF-16 string to associate with t= he underlying synchronization primitive referenced by NT handles exported from the created semaphore.

If this structure is not present, or if pAttributes is set = to NULL, default security descriptor values will be used, and child processes create= d by the application will not inherit the handle, as described in the MSDN documentation for =E2=80=9CSynchronization Object Security and Access Right= s=E2=80=9D1. Further, if the structure is not present, the access rights will be

DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRIT= E

for handles of the following types:

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT

And

GENERIC_ALL

for handles of the following types:

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR

  • If pAttributes is not NULL, pAttribut= es must be a valid pointer to a va= lid SECURITY_ATTRIBUTES value

To export a Windows handle representing the payload of a semaphore, call= :

VkResult vkGetSema=
phoreWin32HandleKHR(
    VkDevice                                    device,
    const VkSemaphoreGetWin32HandleInfoKHR=
*     pGetWin32HandleInfo,
    HANDLE*                                     pHandle);
  • device is the logical device that created the semaphore bei= ng exported.

  • pGetWin32HandleInfo is a pointer to an instance of the VkSemaphoreGetWin32HandleInfoKHR stru= cture containing parameters of the export operation.

  • pHandle will return the Windows handle representing the sem= aphore state.

For handle types defined as NT handles, the handles returned by vkGetSemaphoreWin32HandleKHR are owned by the application. To avoid leaking resources, the application must release ownership of them using the CloseHandle system call when they are no longer need= ed.

Exporting a Windows handle from a semaphore may= have side effects depending on the transference of the specified handle type, as described in Importing Semaphore Payloads.

Valid Usage (Implicit)
  • = device must be a valid VkDev= ice handle

  • pGetWin32HandleInfo must be a valid pointer to a valid VkSemaphoreGetWin32HandleInfoKHR structure

  • pHandle must be a valid pointer t= o a HANDLE value

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkSemaphoreGetWin32HandleInfoKHR structure is defined a= s:

typedef struct VkSemaphoreGetWi=
n32HandleInfoKHR {
    VkStructureType                          sType;
    const void*                              pNext;
    VkSemaphore                              semaphore;
    VkExternalSemaphoreHandleTypeFlagBits    handleType;
} VkSemaphoreGetWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • semaphore is the semaphore from which state will be exporte= d.

  • handleType is the type of handle requested.

The properties of the handle returned depend on the value of handleType. See VkExternalSemaphoreHandleTypeFla= gBits for a description of the properties of the defined external semaphore handle types.

Valid Usage
  • handleType must have been in= cluded in VkExportSemaphoreCreateInfo::handleT= ypes when the semaphore=E2=80=99s current payload was created.

  • If handleType is defined as an NT handle, vkGetSemaphoreWin32HandleKHR must be called no more than once for each valid unique combination of semaphore and handleTyp= e.

  • semaphore must not currently= have its payload replaced by an imported payload as described below in Importing Semaphore Payloads unless that imported payload=E2=80=99s handle type was included in VkExternalSemaphoreProperties::exp= ortFromImportedHandleTypes for handleType.

  • If handleType refers to a handle type with copy payload transference semantics, as defined below in Importing Semaphore Payloads, there must be no queue waiting on s= emaphore.

  • If handleType refers to a handle type with copy payload transference semantics, semaphore mus= t be signaled, or have an associated semaphore signal operation pending execution.

  • handleType must be defined a= s an NT handle or a global share handle.

Valid Usage (Implicit)

To export a POSIX file descriptor representing the payload of a semaphor= e, call:

VkResult vkGetSema=
phoreFdKHR(
    VkDevice                                    device,
    const VkSemaphoreGetFdInfoKHR*        =
      pGetFdInfo,
    int*                            =
            pFd);
  • device is the logical device that created the semaphore bei= ng exported.

  • pGetFdInfo is a pointer to an instance of the VkSemaphoreGetFdInfoKHR structure containing p= arameters of the export operation.

  • pFd will return the file descriptor representing the semaph= ore payload.

Each call to vkGetSemaphoreFdKHR m= ust create a new file descriptor and transfer ownership of it to the application. To avoid leaking resources, the application must release ownership of the file descriptor when it is no longer needed.

Note

Ownership can be released in many ways. For example, the application can call close() on the file desc= riptor, or transfer ownership back to Vulkan by using the file descriptor to import a semaphore payload.

Where supported by the operating system, the implementation must set the file descriptor to be closed automatically when an execve syst= em call is made.

Exporting a file descriptor from a semaphore ma= y have side effects depending on the transference of the specified handle type, as described in Importing Semaphore State.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pGetF= dInfo must be a valid pointer to a= valid VkSemaphoreGetFdInfoKHR structure

  • pFd <= strong class=3D"purple">must be a valid pointer to a int value

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkSemaphoreGetFdInfoKHR structure is defined as:

typedef struct VkSemaphoreGetFd=
InfoKHR {
    VkStructureType                          sType;
    const void*                              pNext;
    VkSemaphore                              semaphore;
    VkExternalSemaphoreHandleTypeFlagBits    handleType;
} VkSemaphoreGetFdInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • semaphore is the semaphore from which state will be exporte= d.

  • handleType is the type of handle requested.

The properties of the file descriptor returned depend on the value of handleType. See VkExternalSemaphoreHandleTypeFla= gBits for a description of the properties of the defined external semaphore handle types.

Valid Usage
  • handleType must have been in= cluded in VkExportSemaphoreCreateInfo::handleT= ypes when semaphore=E2=80=99s current payload was created.

  • semaphore must not currently= have its payload replaced by an imported payload as described below in Importing Semaphore Payloads unless that imported payload=E2=80=99s handle type was included in VkExternalSemaphoreProperties::exp= ortFromImportedHandleTypes for handleType.

  • If handleType refers to a handle type with copy payload transference semantics, as defined below in Importing Semaphore Payloads, there must be no queue waiting on s= emaphore.

  • If handleType refers to a handle type with copy payload transference semantics, semaphore mus= t be signaled, or have an associated semaphore signal operation pending execution.

  • handleType must be defined a= s a POSIX file descriptor handle.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_SEMAPH= ORE_GET_FD_INFO_KHR

  • pNext must be NULL

  • se= maphore must be a valid VkSe= maphore handle

  • h= andleType must be a valid VkExternalSemaphoreHandleTypeFlagBits v= alue

To destroy a semaphore, call:

void vkDestroySemaphore(
    VkDevice                                    device,
    VkSemaphore                                 semaphore,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the semaphore.

  • semaphore is the handle of the semaphore to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted batches that refer to semaphore must have completed execution

  • If VkAllocationCallbacks were provided when semaphore was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when semaphore= was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • If sema= phore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle

  • If pAl= locator is not NULL, pAllocator must be a valid pointer to a valid VkAllocati= onCallbacks structure

  • If semapho= re is a valid handle, it must have= been created, allocated, or retrieved from device

Host Synchronization
  • Host access to semaphore must be externally synchronized

6.4.1. Semaphore Signaling<= /h4>

When a batch is submitted to a queue via a que= ue submission, and it includes semaphores to be signaled, it defines a mem= ory dependency on the batch, and defines semaphore signal operations w= hich set the semaphores to the signaled state.

The first synchronization scope includes every command submitted in the same batch. Semaphore signal operations that are defined by vkQueueSubmi= t additionally include all commands that occur earlier in submission order.

The first access scope includes all memory access performed by the device.

The second access scope = is empty.

6.4.2. Semaphore Waiting &= ; Unsignaling

When a batch is submitted to a queue via a que= ue submission, and it includes semaphores to be waited on, it defines a memory dependency between prior semaphore signal operations and the batch, and defines semaphore unsignal operations which set the semaphores= to the unsignaled state.

The first synchronization scope includes all semaphore signal operations that operate on semaphores waited on in the same batch, and that happen-before the wait completes.

The second synchronization scope includes every command submitted in the same batch. In the case of vkQueueSubmit, the second synchronization= scope is limited to operations on the pipeline stages determined by the destination stage mask specified by the corresponding element of pWaitDstStageMask. Also, in the case of vkQueueSubmit, the second synchroni= zation scope additionally includes all commands that occur later in submission order.

The first access scope i= s empty.

The second access scope includes all memory access performed by the device.

The semaphore unsignal operation happens-after the first set of operatio= ns in the execution dependency, and happens-before the second set of operation= s in the execution dependency.

Note

Unlike fences or events, the act of waiting for a semaphore also unsigna= ls that semaphore. If two operations are separately specified to wait for the same semaphore, and there are no other execution dependencies between those operations, behaviour is undefined. An execution dependency must be present t= hat guarantees that the semaphore unsignal operation for the first of those waits, happens-before the semaphore is signalled again, and before the second unsignal operation. Semaphore waits and signals should thus occur in discrete 1:1 pairs.

Note

A common scenario for using pWaitDstStageMask with values o= ther than VK_PIPELINE_STAGE_ALL_COMMANDS_BIT is when synchronizing a win= dow system presentation operation against subsequent command buffers which render the next frame. In this case, a presentation image must n= ot be overwritten until the presentation operation completes, but other pipeline stages can execute without waiting. A mask of VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT preven= ts subsequent color attachment writes from executing until the semaphore signals. Some implementations may be able to execu= te transfer operations and/or vertex processing work before the semaphore is signaled.

If an image layout transition needs to be performed on a presentable ima= ge before it is used in a framebuffer, that can be performed as the first operation submitted to the queue after acquiring the image, and should not prevent other work from overlapping with the presentation operation. For example, a VkImageMemoryBarrier could use:

  • srcStageMask =3D VK_PIPELINE_STAGE_COLOR_ATTACHMENT_O= UTPUT_BIT

  • srcAccessMask =3D 0

  • dstStageMask =3D VK_PIPELINE_STAGE_COLOR_ATTACHMENT_O= UTPUT_BIT

  • dstAccessMask =3D VK_ACCESS_COLOR_ATTACHMENT_READ_BIT= | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.

  • oldLayout =3D VK_IMAGE_LAYOUT_PRESENT_SRC_KHR<= /p>

  • newLayout =3D VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMA= L

Alternatively, oldLayout can be VK_IMAGE_LAYOUT_UNDEFINED, if the image=E2=80=99s contents need not be preserved.

This barrier accomplishes a dependency chain between previous presentati= on operations and subsequent color attachment output operations, with the layout transition performed in between, and does not introduce a dependency between previous work and any vertex processing stages. More precisely, the semaphore signals after the presentation operation completes, the semaphore wait stalls the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT stage, and there= is a dependency from that same stage to itself with the layout transition performed in between.

6.4.3. Semaphore State = Requirements For Wait Operations

Before waiting on a semaphore, the application = must ensure the semaphore is in a valid state for a wait operation. Specifically, when a semaphore wait and unsignal operation is submitted to a queue:

  • The semaphore must be signaled, or hav= e an associated semaphore signal operation that is pending execution.

  • There must be no other queue waiting o= n the same semaphore when the operation executes.

6.4.4. Importing Semaphore = Payloads

Applications can import a semaphore pa= yload into an existing semaphore using an external semaphore handle. The effects of the import operation will be either temporary or permanent, as specified by the application. If the import is temporary, the implementation mus= t restore the semaphore to its prior permanent state after submitting the next semaphore wait operation. Performing a subsequent temporary import on a semaphore before performing a semaphore wait has no effect on this requirement; the next wait submitted o= n the semaphore must still restore its last= permanent state. A permanent payload import behaves as if the target semaphore was destroyed= , and a new semaphore was created with the same handle but the imported payload. Because importing a semaphore payload temporarily or permanently detaches the existing payload from a semaphore, similar usage restrictions to those applied to vkDestroySemaphore are applied to any command that = imports a semaphore payload. Which of these import types is used is referred to as the import operation= =E2=80=99s permanence. Each handle type supports either one or both types of permanence.

The implementation must perform the im= port operation by either referencing or copying the payload referred to by the specified external semaphore handle, depending on the handle=E2=80=99s type. The import method used is referred to as the handle type=E2=80=99s tran= sference. When using handle types with reference transference, importing a payload to a semaphore adds the semaphore to the set of all semaphores sharing that payload. This set includes the semaphore from which the payload was exported. Semaphore signaling and waiting operations performed on any semaphore in th= e set must behave as if the set were a sing= le semaphore. Importing a payload using handle types with copy transference creates a duplicate copy of the payload at the time of import, but makes no further reference to it. Semaphore signaling and waiting operations performed on the target of copy imports must not affect any other semapho= re or payload.

Export operations have the same transference as the specified handle typ= e=E2=80=99s import operations. Additionally, exporting a semaphore payload to a handle with copy transference has the same side effects on the source semaphore=E2=80=99s pa= yload as executing a semaphore wait operation. If the semaphore was using a temporarily imported payload, the semaphore=E2= =80=99s prior permanent payload will be restored.

Note

The tables Handle Types Supported by VkImportSemaphoreWin32HandleInfoKHR and Handle Types Supported by VkImportSemaphoreFdInfoKHR define the permanence and transference of each handle type.

External synchronization allows implementations to modify an object=E2=80=99s internal state, i.e. payload,= without internal synchronization. However, for semaphores sharing a payload across processes, satisfying the external synchronization requirements of VkSemaphore parameter= s as if all semaphores in the set were the same object is sometimes infeasible. Satisfying the wait operation state requirements would similarly require impractical coordination or levels of trust between processes. Therefore, these constraints only apply to a specific semaphore handle, not to its payload. For distinct semaphore objects which share a payload, if the semaphores are passed to separate queue submission commands concurrently, behavior will be as if the commands were called in an arbitrary sequential order. If the wait operation state requirements are violated for the shared payload by a queue submission command, or if a signal operation is queued for a shared payload that is already signaled or has a pending signal operation, effects must be limited to one or more of the following:

  • Returning VK_ERROR_INITIALIZATION_FAILED from the command w= hich resulted in the violation.

  • Losing the logical device on which the violation occured immediately or at a future time, resulting in a VK_ERROR_DEVICE_LOST error fr= om subsequent commands, including the one causing the violation.

  • Continuing execution of the violating command or operation as if the semaphore wait completed successfully after an implementation-dependent timeout. In this case, the state of the payload becomes undefined, and future operations on semaphores sharing the payload will be subject to these same rules. The semaphore must be destroyed or have i= ts payload replaced by an import operation to again have a well-defined state.

Note

These rules allow processes to synchronize access to shared memory witho= ut trusting each other. However, such processes must still be cautious not to use the shared semaphore for more than synchronizing access to the shared memory. For example, a process should not use a shared semaphore as part of an execution dependency chain that, when complete, leads to objects being destroyed, if it does not trust other processes sharing the semaphore payload.

When a semaphore is using an imported payload, its VkExportSemaphoreCreateInfo::handleT= ypes value is that specified when creating the semaphore from which the payload was exported, rather tha= n that specified when creating the semaphore. Additionally, VkExternalSemaphoreProperties::exportFro= mImportedHandleTypes restricts which handle types can be exported from s= uch a semaphore based on the specific handle type used to import the current payload. Passing a semaphore to vkAcquireNextImageKHR is = equivalent to temporarily importing a semaphore payload to that semaphore.

Note

Because the exportable handle types of an imported semaphore correspond = to its current imported payload, and vkAcquireNextImage= KHR behaves the same as a temporary import operation for which the source semaphore is opaque to the application, applications have no way of determining whether any external handle types can be exported= from a semaphore in this state. Therefore, applications must not attempt = to export external handles from semaphores using a temporarily imported payload from vkAcquireNextImageKHR.

When importing a semaphore payload, it is the responsibility of the application to ensure the external handles meet all valid usage requirements. However, implementations must perform suf= ficient validation of external handles to ensure that the operation results in a valid semaphore which wil= l not cause program termination, device loss, queue stalls, or corruption of other resources when used as allowed according to its import parameters, an= d excepting those side effects allowed for violations of the valid semaphore state for wait operations rules. If the external handle provided does not meet these requirements, the implementation must fail the semaphore pa= yload import operation with the error code VK_ERROR_INVALID_EXTERNAL_HANDLE.

To import a semaphore payload from a Windows handle, call:

VkResult vkImportS=
emaphoreWin32HandleKHR(
    VkDevice                                    device,
    const VkImportSemaphoreWin32HandleInfo=
KHR*  pImportSemaphoreWin32HandleInfo);

Importing a semaphore payload from Windows handles does not transfer ownership of the handle to the Vulkan implementation. For handle types defined as NT handles, the application must release ownership using the CloseHandle system call when the handle is= no longer needed.

Applications can import the same semap= hore payload into multiple instances of Vulkan, into the same instance from which it was exported, and multiple times into a given Vulkan instance.

Valid Usage (Implicit)
  • device must be a valid Vk= Device handle

  • pImportSemaphoreWin32HandleInfo must be a valid pointer to a valid VkImport= SemaphoreWin32HandleInfoKHR structure

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_INVALID_EXTERNAL_HANDLE

The VkImportSemaphoreWin32HandleInfoKHR structure is define= d as:

typedef struct VkImportSemaphor=
eWin32HandleInfoKHR {
    VkStructureType                          sType;
    const void*                              pNext;
    VkSemaphore                              semaphore;
    VkSemaphoreImportFlags                   flags;
    VkExternalSemaphoreHandleTypeFlagBits    handleType;
    HANDLE                                   handle;
    LPCWSTR                                  name;
} VkImportSemaphoreWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • semaphore is the semaphore into which the payload will be imported.

  • flags is a bitmask of VkSemaphor= eImportFlagBits specifying additional parameters for the semaphore payload import operation.

  • handleType specifies the type of handle.

  • handle is the external handle to import, or NULL.

  • name is a NULL-terminated UTF-16 string naming the underlyi= ng synchronization primitive to import, or NULL.

The handle types supported by handleType are:

Table 8. Handle Types Supported by VkImportSemapho= reWin32HandleInfoKHR
Handle Type Transference Permanence Supported

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT

Ref= erence

Tem= porary,Permanent

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT

Ref= erence

Tem= porary,Permanent

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT

Ref= erence

Tem= porary,Permanent

Valid Usage
  • handleType must be a value i= ncluded in the Handle Types Supported by VkImportSemaphoreWin32HandleInfoKHR table.

  • If handleType is not VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT or VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, name<= /code> must be NULL.

  • If handleType is not 0 and handle is= NULL, name must name a valid synchronization primiti= ve of the type specified by handleType.

  • If handleType is not 0 and name is <= code>NULL, handle must be a valid handle of the type specif= ied by handleType.

  • If handle is not NULL, name must be = NULL.

  • If handle is not NULL, it must obey any requirements listed for handleType in external semaphore handle types compatibility.

  • If name is not NULL, it = must obey any requirements listed for handleType in external semaphore handle types compatibility.

Valid Usage (Implicit)
Host Synchronization
  • Host access to semaphore must be externally synchronized

To import a semaphore payload from a POSIX file descriptor, call:

VkResult vkImportS=
emaphoreFdKHR(
    VkDevice                                    device,
    const VkImportSemaphoreFdInfoKHR*     =
      pImportSemaphoreFdInfo);
  • device is the logical device that created the semaphore.

  • pImportSemaphoreFdInfo points to a VkImportSemaphoreFdInfoKHR structure specif= ying the semaphore and import parameters.

Importing a semaphore payload from a file descriptor transfers ownership= of the file descriptor from the application to the Vulkan implementation. The application must not perform any oper= ations on the file descriptor after a successful import.

Applications can import the same semap= hore payload into multiple instances of Vulkan, into the same instance from which it was exported, and multiple times into a given Vulkan instance.

Valid Usage
  • semaphore must not be associ= ated with any queue command that has not yet completed execution on that queue

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_INVALID_EXTERNAL_HANDLE

The VkImportSemaphoreFdInfoKHR structure is defined as:

typedef struct VkImportSemaphor=
eFdInfoKHR {
    VkStructureType                          sType;
    const void*                              pNext;
    VkSemaphore                              semaphore;
    VkSemaphoreImportFlags                   flags;
    VkExternalSemaphoreHandleTypeFlagBits    handleType;
    int                             =
         fd;
} VkImportSemaphoreFdInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • semaphore is the semaphore into which the payload will be imported.

  • flags is a bitmask of VkSemaphor= eImportFlagBits specifying additional parameters for the semaphore payload import operation.

  • handleType specifies the type of fd.

  • fd is the external handle to import.

The handle types supported by handleType are:

Table 9. Handle Types Supported by VkImportSemapho= reFdInfoKHR
Handle Type Transference Permanence Supported

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT

Ref= erence

Tem= porary,Permanent

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT

Cop= y

Tem= porary

Valid Usage
Valid Usage (Implicit)
Host Synchronization
  • Host access to semaphore must be externally synchronized

Additional parameters of a semaphore import operation are specified by VkImportSemaphoreWin32HandleInfoKHR::flags or VkImportSemaphoreFdInfoKHR::flags . Bits which can be set include:

typedef enum VkSemaphoreImportF=
lagBits {
    VK_SEMAPHORE_IMPORT_TEMPORARY_BIT =3D 0x00000001,
    VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR =3D VK_SEMAPHORE_IMPORT_TEMPORARY=
_BIT,
} VkSemaphoreImportFlagBits;

or the equivalent

typedef VkSemaphoreImportFlagBits VkSemaphoreImportFlagBitsKHR=
;

These bits have the following meanings:

  • VK_SEMAPHORE_IMPORT_TEMPORARY_BIT specifies that the semaph= ore payload will be imported only temporarily, as described in Importing Semaphore Payloads, regardless of the permanence of handleType.

typedef VkFlags VkSemaphoreImportFlags;

or the equivalent

typedef VkSemaphoreImportFlags VkSemaphoreImportFlagsKHR;

VkSemaphoreImportFlags is a bitmask type for setting a mask= of zero or more VkSemaphoreImportFlagBits.

6.5. Events

Events are a synchronization primitive that can= be used to insert a fine-grained dependency between commands submitted to the same queue, or between the host and a queue. Events must not be used to insert a depen= dency between commands submitted to different queues. Events have two states - signaled and unsignaled. An application can signal an event, or un= signal it, on either the host or the device. A device can wait for an event to become = signaled before executing further operations. No command exists to wait for an event to become signaled on the host, but the current state of an event can be quer= ied.

Events are represented by VkEvent handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkEvent)

To create an event, call:

VkResult vkCreateE=
vent(
    VkDevice                                    device,
    const VkEventCreateInfo*              =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkEvent*                                    pEvent);
  • device is the logical device that creates the event.

  • pCreateInfo is a pointer to an instance of the VkEventCreateInfo structure which contains information about h= ow the event is to be created.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pEvent points to a handle in which the resulting event obje= ct is returned.

When created, the event object is in the unsignaled state.

Valid Usage (Implicit)
  • device <= strong class=3D"purple">must be a valid VkDevice hand= le

  • pCreateInf= o must be a valid pointer to a val= id VkEventCreateInfo structure

  • If pAllocat= or is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • pEvent <= strong class=3D"purple">must be a valid pointer to a VkEvent= handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkEventCreateInfo structure is defined as:

typedef struct VkEventCreateInf=
o {
    VkStructureType       sType;
    const void*           pNext;
    VkEventCreateFlags    flags;
} VkEventCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_EVENT_CREATE= _INFO

  • pNext must be NULL

  • flags must be 0

typedef VkFlags VkEventCreateFlags;

VkEventCreateFlags is a bitmask type for setting a mask, bu= t is currently reserved for future use.

To destroy an event, call:

void vkDestroyEvent(
    VkDevice                                    device,
    VkEvent                                     event,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the event.

  • event is the handle of the event to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to event must have completed execution

  • If VkAllocationCallbacks were provided when event= was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when event was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device = must be a valid VkDevice han= dle

  • If event= is not VK_NULL_HANDLE, event must be a valid VkEvent handle

  • If pAlloca= tor is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • If event is= a valid handle, it must have been create= d, allocated, or retrieved from device

Host Synchronization
  • Host access to event must= be externally synchronized

To query the state of an event from the host, call:

VkResult vkGetEven=
tStatus(
    VkDevice                                    device,
    VkEvent                                     event);
  • device is the logical device that owns the event.

  • event is the handle of the event to query.

Upon success, vkGetEventStatus returns the state of the eve= nt object with the following return codes:

Table 10. Event Object Status Codes
Status Meaning

VK_EVENT_SET

The= event specified by event is signaled.

VK_EVENT_RESET

The= event specified by event is unsignaled.

If a vkCmdSetEvent or vkCmdResetEvent command = is in a command buffer that is in the pending state, then the value returned by this command may immedi= ately be out of date.

The state of an event can be updated b= y the host. The state of the event is immediately changed, and subsequent calls to vkGetEventStatus will return the new state. If an event is already in the requested state, then updating it to the same state has no effect.

Valid Usage (Implicit)
  • device must be a valid VkDevice h= andle

  • event = must be a valid VkEvent hand= le

  • event must have been created, allocated, or retrie= ved from device

Return Codes
Success
  • VK_EVENT_SET

  • VK_EVENT_RESET

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

To set the state of an event to signaled from the host, call:

VkResult vkSetEven=
t(
    VkDevice                                    device,
    VkEvent                                     event);
  • device is the logical device that owns the event.

  • event is the event to set.

When vkSetEvent is executed on the host, it defines an <= em>event signal operation which sets the event to the signaled state.

If event is already in the signaled state when = vkSetEvent is executed, then vkSetEvent has no effect, and no event signa= l operation occurs.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle<= /p>

  • event must be a valid VkEvent handle

  • event must have been created, allocated, or retrieved fr= om device

Host Synchronization
  • Host access to event must= be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

To set the state of an event to unsignaled from the host, call:

VkResult vkResetEv=
ent(
    VkDevice                                    device,
    VkEvent                                     event);
  • device is the logical device that owns the event.

  • event is the event to reset.

When vkResetEvent is executed on the host, it defines = an event unsignal operation which resets the event to the unsignaled state.

If event is already in the unsignaled state when vkResetEvent is executed, then vkResetEvent has no effect, and no event u= nsignal operation occurs.

Valid Usage
  • event must not be waited on = by a vkCmdWaitEvents command that is currently executing

Valid Usage (Implicit)
  • device must be a valid VkDevice handl= e

  • event must be a valid VkEvent handle

  • event must have been created, allocated, or retrieved = from device

Host Synchronization
  • Host access to event must= be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The state of an event can also be upda= ted on the device by commands inserted in command buffers.

To set the state of an event to signaled from a device, call:

void vkCmdSetEvent(
    VkCommandBuffer                             commandBuffer,
    VkEvent                                     event,
    VkPipelineStageFlags                        stageMask);
  • commandBuffer is the command buffer into which the command = is recorded.

  • event is the event that will be signaled.

  • stageMask specifies the so= urce stage mask used to determine when the event is signaled.

When vkCmdSetEvent is submitted to a queue, it define= s an execution dependency on commands that were submitted before it, and defines an event signal operation which sets the event to the signaled state.

The first synchronization scope includes all commands that occur earlier in submission order. The synchronization scope is limited to operations on the pipeline stages determined by the source stage mask specified by stageMask.

If event is already in the signaled state when vkCmdSetEvent is executed on the device, then vkCmdSetEvent has no effect= , no event signal operation occurs, and no execution dependency is generated.

Valid Usage
  • stageMask must not include <= code>VK_PIPELINE_STAGE_HOST_BIT

  • If the geometry shaders feature is not enabled, stageMask must = not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the tessellation shaders feature is not enabled, stageMask mus= t not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • commandBuffer=E2=80=99s current device mask must include exactly one physical device.

Valid Usage (Implicit)
  • commandB= uffer must be a valid VkComm= andBuffer handle

  • event must be a valid VkEvent handle<= /p>

  • stageMask must be a valid combination of VkPipelineStageFlagBits values

  • stageM= ask must not be 0

  • commandB= uffer must be in the recording state

  • The VkComm= andPool that commandBuffer was allocated from must support graphics, or compute operations

  • This command must only be called outside of a render pass instance<= /p>

  • Both of commandBuff= er, and event must ha= ve been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Gra= phics
Compute

To set the state of an event to unsignaled from a device, call:

void vkCmdResetEvent(
    VkCommandBuffer                             commandBuffer,
    VkEvent                                     event,
    VkPipelineStageFlags                        stageMask);
  • commandBuffer is the command buffer into which the command = is recorded.

  • event is the event that will be unsignaled.

  • stageMask is a bitmask of VkPipeli= neStageFlagBits specifying the source stage mask used to determine when the event is unsignaled.

When vkCmdResetEvent is submitted to a queue, it de= fines an execution dependency on commands that were submitted before it, and defines an event unsignal operation which resets the event to the unsignaled state.

The first synchronization scope includes all commands that occur earlier in submission order. The synchronization scope is limited to operations on the pipeline stages determined by the source stage mask specified by stageMask.

If event is already in the unsignaled state when vkCmdResetEvent is executed on the device, then vkCmdResetEvent has no= effect, no event unsignal operation occurs, and no execution dependency is generated.<= /p>

Valid Usage
  • stageMask must not include <= code>VK_PIPELINE_STAGE_HOST_BIT

  • If the geometry shaders feature is not enabled, stageMask must = not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the tessellation shaders feature is not enabled, stageMask mus= t not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • When this command executes, event mus= t not be waited on by a vkCmdWaitEvents command that is currently executing

  • commandBuffer=E2=80=99s current device mask must include exactly one physical device.

Valid Usage (Implicit)
  • comman= dBuffer must be a valid VkCo= mmandBuffer handle

  • event <= strong class=3D"purple">must be a valid VkEvent handl= e

  • stageMask<= /code> must be a valid combination of VkPipelineStageFlagBits values

  • stag= eMask must not be 0

  • comman= dBuffer must be in the recording state

  • The VkCo= mmandPool that commandBuffer was allocated from must support graphics, or compute operations

  • This command must only be called outside of a render pass instance=

  • Both of commandBu= ffer, and event must = have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Gra= phics
Compute

To wait for one or more events to enter the signaled state on a device, call:

void vkCmdWaitEvents(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    eventCount,
    const VkEvent*                        =
      pEvents,
    VkPipelineStageFlags                        srcStageMask,
    VkPipelineStageFlags                        dstStageMask,
    uint32_t                                    memoryBarrierCount,
    const VkMemoryBarrier*                =
      pMemoryBarriers,
    uint32_t                                    bufferMemoryBarrierCount,
    const VkBufferMemoryBarrier*          =
      pBufferMemoryBarriers,
    uint32_t                                    imageMemoryBarrierCount,
    const VkImageMemoryBarrier*           =
      pImageMemoryBarriers);
  • commandBuffer is the command buffer into which the command = is recorded.

  • eventCount is the length of the pEvents array.=

  • pEvents is an array of event object handles to wait on.

  • srcStageMask is a bitmask of VkPip= elineStageFlagBits specifying the source stage mask.

  • dstStageMask is a bitmask of VkPip= elineStageFlagBits specifying the destination stage mask.

  • memoryBarrierCount is the length of the pMemoryBarrie= rs array.

  • pMemoryBarriers is a pointer to an array of VkBufferMemoryBarrier structures.

  • imageMemoryBarrierCount is the length of the pImageMemoryBarriers array.

  • pImageMemoryBarriers is a pointer to an array of VkImageMemoryBarrier structures.

When vkCmdWaitEvents is submitted to a queue, it defines a = memory dependency between prior event signal operations on the same queue or the host, and subsequent commands. vkCmdWaitEvents must not be = used to wait on event signal operations occuring on other queues.

The first synchronization scope only includes event signal operations th= at operate on members of pEvents, and the operations that happene= d-before the event signal operations. Event signal operations performed by vkCmdSetEvent that = occur earlier in submission order are included in t= he first synchronization scope, if the = logically latest pipeline stage in their stageMask paramet= er is logically earlier than or equal to the logically latest pipeline stage in srcStageMask. Event signal operations performed by vkSetEvent are only in= cluded in the first synchronization scope if VK_PIPELINE_STAGE_HOST_BIT = is included in srcStageMask.

The second synchronization scope includes all commands that occur later in submission order. The second synchronization scope is limited to operations on the pipeline stages determined by the destination= stage mask specified by dstStageMask.

The first access scope i= s limited to access in the pipeline stages determined by the source stage mask specified by srcStageMask. Within that, the first access scope only includes the first access scopes defined by elements of the pMemoryBarriers, pBufferMemoryBarriers and pImageMemoryBarriers ar= rays, which each define a set of memory barriers. If no memory barriers are specified, then the first access scope includes n= o accesses.

The second access scope = is limited to access in the pipeline stages determined by the destination stage mask specified by dstStageMask. Within that, the second access scope only includes the second access scopes defined by elements of the pMemoryBarriers, pBufferMemoryBarriers and pImageMemoryBarriers ar= rays, which each define a set of memory barriers. If no memory barriers are specified, then the second access scope includes no accesses.

Note

vkCmdWaitEvents is used with vkCmdSe= tEvent to define a memory dependency between two sets of action commands, roughly in the same way as pipeline barriers, but split into two commands such that work between the two may execute unhindered.

Note

Applications should be careful to avoi= d race conditions when using events. There is no direct ordering guarantee between a vkCmdReset= Event command and a vkCmdWaitEvents command submitted after = it, so some other execution dependency must be includ= ed between these commands (e.g. a semaphore).

Valid Usage
  • srcStageMask must be the bit= wise OR of the stageMask parameter used in previous calls to vkCmdSetEvent with any of = the members of pEvents and VK_PIPELINE_STAGE_HOST_BIT= if any of the members of pEvents was set using vkSetEvent

  • If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the tessellation shaders feature is not enabled, srcStageMask = must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • If the tessellation shaders feature is not enabled, dstStageMask = must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • If pEvents includes one or more events that will be signaled b= y vkSetEvent after commandBuffer has been submitted= to a queue, then vkCmdWaitEvents must not be called inside a render pass instance

  • Any pipeline stage included in srcStageMask or dstStageM= ask must be supported by the capabilities of = the queue family specified by the queueFamilyIndex member of the Vk= CommandPoolCreateInfo structure that was used to create the VkCommandPool that commandBuffer was allocated from, as specified in the table of supported pipeline stages.

  • Each element of pMemoryBarriers, pBufferMemoryBarriers or pImageMemoryBarriers must no= t have any access flag included in its srcAccessMask member if that bit is not supported by any o= f the pipeline stages in srcStageMask, as specified in the table of supported access types.

  • Each element of pMemoryBarriers, pBufferMemoryBarriers or pImageMemoryBarriers must no= t have any access flag included in its dstAccessMask member if that bit is not supported by any o= f the pipeline stages in dstStageMask, as specified in the table of supported access types.

  • commandBuffer=E2=80=99s current device mask must include exactly one physical device.

Valid Usage (Implicit)
  • comman= dBuffer must be a valid VkCo= mmandBuffer handle

  • pEvents must be a valid pointer to an array of= eventCount valid VkEvent handles

  • srcStag= eMask must be a valid combination = of VkPipelineStageFlagBits values

  • s= rcStageMask must not be 0

  • dstStag= eMask must be a valid combination = of VkPipelineStageFlagBits values

  • d= stStageMask must not be 0

  • If m= emoryBarrierCount is not 0, pMemoryBarriers must be a valid pointer to an array of = memoryBarrierCount valid VkMemoryBarrier structur= es

  • If <= code>bufferMemoryBarrierCount is not 0, pBufferMe= moryBarriers must be a valid point= er to an array of bufferMemoryBarrierCount valid VkBuffe= rMemoryBarrier structures

  • If imageMemoryBarrierCount is not 0, pImageMemor= yBarriers must be a valid pointer = to an array of imageMemoryBarrierCount valid VkImageMemo= ryBarrier structures

  • comman= dBuffer must be in the recording state

  • The VkCo= mmandPool that commandBuffer was allocated from must support graphics, or compute operations

  • eventCo= unt must be greater than 0

  • Both of commandBu= ffer, and the elements of pEvents must have been created, allocated, or retrieved from the same = VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

6.6. Pipeline Barriers

vkCmdPipelineBarrier is a synchronization comm= and that inserts a dependency between commands submitted to the same queue, or between command= s in the same subpass.

To record a pipeline barrier, call:

void vkCmdPipelineBarrier(
    VkCommandBuffer                             commandBuffer,
    VkPipelineStageFlags                        srcStageMask,
    VkPipelineStageFlags                        dstStageMask,
    VkDependencyFlags                           dependencyFlags,
    uint32_t                                    memoryBarrierCount,
    const VkMemoryBarrier*                =
      pMemoryBarriers,
    uint32_t                                    bufferMemoryBarrierCount,
    const VkBufferMemoryBarrier*          =
      pBufferMemoryBarriers,
    uint32_t                                    imageMemoryBarrierCount,
    const VkImageMemoryBarrier*           =
      pImageMemoryBarriers);

When vkCmdPipelineBarrier is submitted to a qu= eue, it defines a memory dependency between commands that were submitted before it, and those submitted after it.

If vkCmdPipelineBarrier was recorded outside a= render pass instance, the first synchronization scope includes all commands that occur earlier in submission order. If vkCmdPipelineBarrier was recorded inside a ren= der pass instance, the first synchronization scope includes only commands that occur earlier i= n submission order within the same subpass. In either case, the first synchronization scope is limited to operations on the pipeline stages determined by the source stage mask specified by srcStageMask.

If vkCmdPipelineBarrier was recorded outside a= render pass instance, the second synchronization scope includes all commands that occur later in submission order. If vkCmdPipelineBarrier was recorded inside a ren= der pass instance, the second synchronization scope includes only commands that occur later in submission order within the same subpass. In either case, the second synchronization scope is limited to operations o= n the pipeline stages determined by the destination stage mask specified by dstStageMask.

The first access scope i= s limited to access in the pipeline stages determined by the source stage mask specified by srcStageMask. Within that, the first access scope only includes the first access scopes defined by elements of the pMemoryBarriers, pBufferMemoryBarriers and pImageMemoryBarriers ar= rays, which each define a set of memory barriers. If no memory barriers are specified, then the first access scope includes n= o accesses.

The second access scope = is limited to access in the pipeline stages determined by the destination stage mask specified by dstStageMask. Within that, the second access scope only includes the second access scopes defined by elements of the pMemoryBarriers, pBufferMemoryBarriers and pImageMemoryBarriers ar= rays, which each define a set of memory barriers. If no memory barriers are specified, then the second access scope includes no accesses.

If dependencyFlags includes VK_DEPENDENCY_BY_REGION_B= IT, then any dependency between framebuffer-spa= ce pipeline stages is framebuffer-local - otherwise it i= s framebuffer-global.

Valid Usage
  • If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the tessellation shaders feature is not enabled, srcStageMask = must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • If the tessellation shaders feature is not enabled, dstStageMask = must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • If vkCmdPipelineBarrier is called within a render pass instanc= e, the render pass must have been created wi= th at least one VkSubpassDependency instance in VkRenderPassCreateInfo::pDependencies that expres= ses a dependency from the current subpass to itself, and for which srcStageMask contains a subset of the bit values in VkSubpassDependency::srcStageMask, dstStage= Mask contains a subset of the bit values in VkSubpassDependency::dstStageMask, and depe= ndencyFlags is equal to VkSubpassDependency::dependencyFlags.=

  • If vkCmdPipelineBarrier is called within a render pass inst= ance, for each element of pMemoryBarriers and pImageMemoryBarriers, the render pass must have been defined with a VkSubpassDependency self-dependency for the current subpass = with valid srcStageMask, dstStageMask, and depen= dencyFlags values such that Vk*Barrier::srcAccessMask contai= ns a subset of the bit values in VkSubpassDependency::srcAccessMask<= /code> and Vk*Barrier::dstAccessMask contains a subset of th= e bit values in VkSubpassDependency::dstAccessMask.

  • If vkCmdPipelineBarrier is called within a render pass instanc= e, bufferMemoryBarrierCount must be 0

  • If vkCmdPipelineBarrier is called within a render pass instanc= e, the image member of any element of pImageMemoryBarriers<= /code> must be equal to one of the elements of <= code>pAttachments that the current framebuffer was created with, that is also referred to= by one of the elements of the pColorAttachments, pResolveAttachments or pDepthStencilAttachment me= mbers of the VkSubpassDescription instance that the current subpass was created with

  • If vkCmdPipelineBarrier is called within a render pass instanc= e, the oldLayout and newLayout members of any elemen= t of pImageMemoryBarriers must be= equal to the layout member of an element of the pColorAttachments, pResolveAttachments= or pDepthStencilAttachment members of the VkSubpassDescript= ion instance that the current subpass was created with, that refers to the same image

  • If vkCmdPipelineBarrier is called within a render pass instanc= e, the oldLayout and newLayout members of an element= of pImageMemoryBarriers must be= equal

  • If vkCmdPipelineBarrier is called within a render pass instanc= e, the srcQueueFamilyIndex and dstQueueFamilyIndex m= embers of any element of pImageMemoryBarriers m= ust be VK_QUEUE_FAMILY_IGNORED

  • Any pipeline stage included in srcStageMask or dstStageM= ask must be supported by the capabilities of = the queue family specified by the queueFamilyIndex member of the Vk= CommandPoolCreateInfo structure that was used to create the VkCommandPool that commandBuffer was allocated from, as specified in the table of supported pipeline stages.

  • Each element of pMemoryBarriers, pBufferMemoryBarriers and pImageMemoryBarriers must no= t have any access flag included in its srcAccessMask member if that bit is not supported by any o= f the pipeline stages in srcStageMask, as specified in the table of supported access types.

  • Each element of pMemoryBarriers, pBufferMemoryBarriers and pImageMemoryBarriers must no= t have any access flag included in its dstAccessMask member if that bit is not supported by any o= f the pipeline stages in dstStageMask, as specified in the table of supported access types.

  • If vkCmdPipelineBarrier is called outside of a render pass instance, dependencyFlags must not include VK_DEPENDENCY_VIEW_LOCAL_BIT

Valid Usage (Implicit)
  • c= ommandBuffer must be a valid VkCommandBuffer handle

  • sr= cStageMask must be a valid combina= tion of VkPipelineStageFlagBits values

  • srcStageMask must not be 0

  • ds= tStageMask must be a valid combina= tion of VkPipelineStageFlagBits values

  • dstStageMask must not be 0

  • dependencyFlags must be a valid c= ombination of VkDependencyFlagBits values

  • If memoryBarrierCount is not 0, pMemoryBarriers<= /code> must be a valid pointer to an arra= y of memoryBarrierCount valid VkMemoryBarrier str= uctures

  • = If bufferMemoryBarrierCount is not 0, pBuf= ferMemoryBarriers must be a valid = pointer to an array of bufferMemoryBarrierCount valid Vk= BufferMemoryBarrier structures

  • = If imageMemoryBarrierCount is not 0, pImage= MemoryBarriers must be a valid poi= nter to an array of imageMemoryBarrierCount valid VkImag= eMemoryBarrier structures

  • c= ommandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute= operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Tra= nsfer
Graphics
Compute

Bits which can be set in vkCmdPi= pelineBarrier::dependencyFlags, specifying how execution and memory dependencies are formed, are:

typedef enum VkDependencyFlagBi=
ts {
    VK_DEPENDENCY_BY_REGION_BIT =3D 0x00000001,
    VK_DEPENDENCY_DEVICE_GROUP_BIT =3D 0x00000004,
    VK_DEPENDENCY_VIEW_LOCAL_BIT =3D 0x00000002,
    VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR =3D VK_DEPENDENCY_VIEW_LOCAL_BIT,
    VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR =3D VK_DEPENDENCY_DEVICE_GROUP_BIT,
} VkDependencyFlagBits;
typedef VkFlags VkDependencyFlags;

VkDependencyFlags is a bitmask type for setting a mask of z= ero or more VkDependencyFlagBits.

6.6.= 1. Subpass Self-dependency

If vkCmdPipelineBarrier is called inside a render pass inst= ance, the following restrictions apply. For a given subpass to allow a pipeline barrier, the render pass must declare a self-dependency from that subpass to itself. That is, there must exist a VkSubpa= ssDependency in the subpass dependency list for the render pass with srcSubpass and dstSubpass equal to that subpass index. More than one self-dependency can be decl= ared for each subpass. Self-dependencies must only include pipel= ine stage bits that are graphics stages. Self-dependencies must not have any earli= er pipeline stages depend on any later pipeline stages (according to the order of graphics pipeline stages), unles= s all of the stages are framebuffer-space stages. If the source and destination stage masks both include framebuffer-space stages, then dependencyFlags must include VK_DEPENDENCY_BY_REGION_BIT. If the subpass has more than one view, then dependencyFlags must include VK_DEPENDENCY_VIEW_LOCAL_BIT.

A vkCmdPipelineBarrier command inside a render pass instanc= e must be a subset of one of the self-dependencies of the subpass it is used= in, meaning that the stage masks and access masks must= each include only a subset of the bits of the corresponding mask in that self-dependency. If the self-dependency has VK_DEPENDENCY_BY_REGION_BIT or VK_DEPENDENCY_VIEW_LOCAL_BIT set, then so must the pipeline barrier. Pipeline barriers within a render pass instance ca= n only be types VkMemoryBarrier or VkImageMemoryBarrier. If a VkImageMemoryBarrier is used, the image and image subreso= urce range specified in the barrier must be a = subset of one of the image views used by the framebuffer in the current subpass. Additionally, oldLayout must= be equal to newLayout, and both the srcQueueFamilyIndex and dstQueueFamilyIndex <= strong class=3D"purple">must be VK_QUEUE_FAMILY_IGNORED.

6.7. Memory Barriers

Memory barriers are used to explicitly control access to buffer= and image subresource ranges. Memory barriers are used to transfer ownership between queue families, change image layouts, and define availability and visibility operations. They explicitly define the access types and buffer and image subresource ranges that are included in the access scopes of a memory dependency that is created by a synchronization command that includes them.=

6.7.1. Global Memory Barr= iers

Global memory barriers apply to memory accesses involving all memory obj= ects that exist at the time of its execution.

The VkMemoryBarrier structure is defined as:

typedef struct VkMemoryBarrier =
{
    VkStructureType    sType;
    const void*        pNext;
    VkAccessFlags      srcAccessMask;
    VkAccessFlags      dstAccessMask;
} VkMemoryBarrier;

The first access scope i= s limited to access types in the source access mask specified by srcAccessMask.

The second access scope = is limited to access types in the destination access mask specified by dstAccessMask.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_MEMORY_BARRIER=

  • pNext must be NULL

  • srcAcc= essMask must be a valid combinatio= n of VkAccessFlagBits values

  • dstAcc= essMask must be a valid combinatio= n of VkAccessFlagBits values

6.7.2. Buffer Memory Barr= iers

Buffer memory barriers only apply to memory accesses involving a specifi= c buffer range. That is, a memory dependency formed from an buffer memory barrier is scoped to access via the specified buffer range. Buffer memory barriers can also be used t= o define a queue family ownership transfer for th= e specified buffer range.

The VkBufferMemoryBarrier structure is defined as:

typedef struct VkBufferMemoryBa=
rrier {
    VkStructureType    sType;
    const void*        pNext;
    VkAccessFlags      srcAccessMask;
    VkAccessFlags      dstAccessMask;
    uint32_t           srcQueueFamilyIndex;
    uint32_t           dstQueueFamilyIndex;
    VkBuffer           buffer;
    VkDeviceSize       offset;
    VkDeviceSize       size;
} VkBufferMemoryBarrier;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • srcAccessMask is a bitmask of VkAccessFla= gBits specifying a source access mask.

  • dstAccessMask is a bitmask of VkAccessFla= gBits specifying a destination access mask.

  • srcQueueFamilyIndex is the source queue family for a queue family ownership transfer.

  • dstQueueFamilyIndex is the destination queue family for a queue family ownership transfer.

  • buffer is a handle to the buffer whose backing memory is af= fected by the barrier.

  • offset is an offset in bytes into the backing memory for buffer; this is relative to the base offset as bound to the bu= ffer (see vkBindBufferMemory).

  • size is a size in bytes of the affected area of backing mem= ory for buffer, or VK_WHOLE_SIZE to use the range from offset to the end of the buffer.

The first access scope i= s limited to access to memory through the specified buffer range, via access types in the source access mask specified by srcAccessMask. If srcAccessMask includes VK_ACCESS_HOST_WRITE_BIT, memory writes performed by that access type are also made visible, as that access type is not performed through a resource.

The second access scope = is limited to access to memory through the specified buffer range, via access types in the destination access mask. specified by dstAccessMask. If dstAccessMask includes VK_ACCESS_HOST_WRITE_BIT or VK_ACCESS_HOST_READ_BIT, available memory writes are also made= visible to accesses of those types, as those access types are not performed through a resource.

If srcQueueFamilyIndex is not equal to dstQueueFamily= Index, and srcQueueFamilyIndex is equal to the current queue family, then= the memory barrier defines a queue family release operation for the specified buffer range, and the second access scope includes no access, as if dstAccessMask was 0.

If dstQueueFamilyIndex is not equal to srcQueueFamily= Index, and dstQueueFamilyIndex is equal to the current queue family, then= the memory barrier defines a queue family acquire operation for the specified buffer range, and the first access scope includes no access, as if srcAccessMask was 0.

Valid Usage
  • offset must be less than the= size of buffer

  • If size is not equal to VK_WHOLE_SIZE, size= must be greater than 0

  • If size is not equal to VK_WHOLE_SIZE, size= must be less than or equal to than the size of buffer minus offs= et

  • If buffer was created with a sharing mode of VK_SHARING_MODE_CONCURRENT, at least one of srcQueueFamilyIndex and dstQueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED

  • If buffer was created with a sharing mode of VK_SHARING_MODE_CONCURRENT, and one of srcQueueFamilyInd= ex and dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, the other must be VK_QUEUE_FAMILY_IGNOR= ED or a special queue family reserved for external memory ownership transfers, as described in Queue Family Ownership Transfer.

  • If buffer was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE and srcQueueFamilyIndex= is VK_QUEUE_FAMILY_IGNORED, dstQueueFamilyIndex must also be VK_QUEUE_FAMILY_IGNORED

  • If buffer was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE and srcQueueFamilyIndex= is not VK_QUEUE_FAMILY_IGNORED, it must be a valid queue family or a special queue family reserved for external memory transfers, as described in Queue Family Ownership Transf= er.

  • If buffer was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE and dstQueueFamilyIndex= is not VK_QUEUE_FAMILY_IGNORED, it must be a valid queue family or a special queue family reserved for external memory transfers, as described in Queue Family Ownership Transf= er.

  • If buffer was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, and srcQueueFamilyIndex and dstQueueFamilyIndex are not VK_QUEUE_FAMILY_IGNORED, at least one of them must be the same as the= family of the queue that will execute this barrier

  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_BUFFER_M= EMORY_BARRIER

  • pNext= must be NULL

  • = srcAccessMask must be a valid comb= ination of VkAccessFlagBits values

  • = dstAccessMask must be a valid comb= ination of VkAccessFlagBits values

  • buffer<= /code> must be a valid VkBuffer handle

6.7.3. Image Memory Barrie= rs

Image memory barriers only apply to memory accesses involving a specific image subresource range. That is, a memory dependency formed from an image memory barrier is scoped to access via the specified image subresource range. Image memory barriers can also be used to= define image layout transitions or a queue family ownership transfer for th= e specified image subresource range.

The VkImageMemoryBarrier structure is defined as:

typedef struct VkImageMemoryBar=
rier {
    VkStructureType            sType;
    const void*                pNext;
    VkAccessFlags              srcAccessMask;
    VkAccessFlags              dstAccessMask;
    VkImageLayout              oldLayout;
    VkImageLayout              newLayout;
    uint32_t                   srcQueueFamilyIndex;
    uint32_t                   dstQueueFamilyIndex;
    VkImage                    image;
    VkImageSubresourceRange    subresourceRange;
} VkImageMemoryBarrier;

The second access scope = is limited to access to memory through the specified image subresource range, via access types in the destination access mask specified by dstAccessMask. If dstAccessMask includes VK_ACCESS_HOST_WRITE_BIT or VK_ACCESS_HOST_READ_BIT, available memory writes are also made= visible to accesses of those types, as those access types are not performed through a resource.

If srcQueueFamilyIndex is not equal to dstQueueFamily= Index, and srcQueueFamilyIndex is equal to the current queue family, then= the memory barrier defines a queue family release operation for the specified image subresource range, and the second access scope includes no access, as if dstAccessMask was 0.

If dstQueueFamilyIndex is not equal to srcQueueFamily= Index, and dstQueueFamilyIndex is equal to the current queue family, then= the memory barrier defines a queue family acquire operation for the specified image subresource range, and the first access scope includes no access, as if srcAccessMask= was 0.

If oldLayout is not equal to newLayout, then t= he memory barrier defines an image layout transition for the specified image subresource range.

Layout transitions that are performed via image memory barriers execute = in their entirety in submission order, relative to other image layout transitions submitted to the same queue, including those performed by render passes. In effect there is an implicit execution dependency from each such layout transition to all layout transitions previously submitted to the same queue= .

The image layout of each image subresource of a depth/stencil image crea= ted with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT= is dependent on the last sample locations used to render to the image subresource as a depth/stencil attachment, thus when the image= member of an VkImageMemoryBarrier is an image created with this flag = the application can chain a VkSampleLocationsInfoEXT structure to the pNext chain of VkImageMemoryBarrier to specify th= e sample locations to use during the image layout transition.

If the VkSampleLocationsInfoEXT structure in the pNex= t chain of VkImageMemoryBarrier does not match the sample location state = last used to render to the image subresource range specified by subresourceRange or if no VkSampleLocationsInfoEXT structure is in the pNext chain of VkImageMemoryBarrier then t= he contents of the given image subresource range becomes undefined as if oldLayout would equal VK_IMAGE_LAYOUT_UNDEFINED.

If image has a multi-planar format and the image is dis= joint, then including VK_IMAGE_ASPECT_COLOR_BIT in the aspectMask member of subresourceRange is equivalent to including VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , and (for three-plane formats only) VK_IMAGE_ASPECT_PLANE_2_BIT.

Valid Usage
  • oldLayout must be VK_I= MAGE_LAYOUT_UNDEFINED or the current layout of the image subresources affected by the barrier

  • newLayout must not be = VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED

  • If image was created with a sharing mode of VK_SHARING_MODE_CONCURRENT, at least one of srcQueueFamilyIndex and dstQueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED

  • If image was created with a sharing mode of VK_SHARING_MODE_CONCURRENT, and one of srcQueueFamilyInd= ex and dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, the other must be VK_QUEUE_FAMILY_IGNOR= ED or a special queue family reserved for external memory transfers, as described in Queue Family Ownership Transfer.

  • If image was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE and srcQueueFamilyIndex= is VK_QUEUE_FAMILY_IGNORED, dstQueueFamilyIndex must also be VK_QUEUE_FAMILY_IGNORED.

  • If image was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE and srcQueueFamilyIndex= is not VK_QUEUE_FAMILY_IGNORED, it must be a valid queue family or a special queue family reserved for external memory transfers, as described in Queue Family Ownership Transf= er.

  • If image was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE and dstQueueFamilyIndex= is not VK_QUEUE_FAMILY_IGNORED, it must be a valid queue family or a special queue family reserved for external memory transfers, as described in Queue Family Ownership Transf= er.

  • If image was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, and srcQueueFamilyIndex and dstQueueFamilyIndex are not VK_QUEUE_FAMILY_IGNORED, at least one of them must be the same as the= family of the queue that will execute this barrier

  • subresourceRange.baseMipLevel must be less than the mipLevels specified in VkImageCreateInfo when image was created

  • If subresourceRange.levelCount is not VK_REMAINING_MIP_LEVELS, subresourceR= ange.baseMipLevel + subresourceRange.levelCount must be less than or equal to the mipLevels specified in VkImageCreateInf= o when image was created

  • subresourceRange.baseArrayLayer must<= /strong> be less than the arrayLayers specified in VkImageCreateInfo<= /a> when image was created

  • If subresourceRange.layerCount is not VK_REMAINING_ARRAY_LAYERS, subresourceRange.baseArrayLayer +=20 subresourceRange.layerCount mu= st be less than or equal to the arrayLayers specified in VkImageCreateInfo<= /a> when image was created

  • If image has a depth/stencil format with both depth and stenci= l components, then the aspectMask member of subresourceRan= ge must include both VK_IMAGE_ASPECT_D= EPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT

  • If image has a single-plane color format or is not disjoin= t, then the aspectMask member of subresourceRange must be VK_IMAGE_ASPECT_COLOR_BIT

  • If image has a multi-planar format and the image is disjoi= nt, then the aspectMask member of subresourceRange must include either at least one of VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT, and VK_IMAGE_ASPECT_PLANE_2_BIT; or must<= /strong> include VK_IMAGE_ASPECT_COLOR_BIT

  • If image has a multi-planar format with only two planes, then = the aspectMask member of subresourceRange must not include VK_IMAGE_ASPECT_PLANE_2_BIT

  • If either oldLayout or newLayout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then image must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set=

  • If either oldLayout or newLayout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL then im= age must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set

  • If either oldLayout or newLayout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then ima= ge must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set

  • If either oldLayout or newLayout is VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL the= n image must have been created= with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set

  • If either oldLayout or newLayout is VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL the= n image must have been created= with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set

  • If either oldLayout or newLayout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then image must have been created with VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set

  • If either oldLayout or newLayout is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then image <= strong class=3D"purple">must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT set

  • If either oldLayout or newLayout is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then image <= strong class=3D"purple">must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT set

  • If image is non-sparse then it must be bound completely and contiguously to a single VkDeviceMemory object

Valid Usage (Implicit)
  • sType = must be VK_STRUCTURE_TYPE_IMAGE_MEM= ORY_BARRIER

  • pNext = must be NULL or a pointer to= a valid instance of VkSampleLocationsInfoEXT=

  • s= rcAccessMask must be a valid combi= nation of VkAccessFlagBits values

  • d= stAccessMask must be a valid combi= nation of VkAccessFlagBits values

  • oldLa= yout must be a valid newLa= yout must be a valid image must be a valid VkImage = handle

  • subresourceRange must be a valid= VkImageSubresourceRange structure

6.7.4. Queue Family Ownership Tr= ansfer

Resources created with a VkSharingMode of VK_SHARING_MODE_EXCLUSIVE must have their ownership explicitly transferred from one queue family to another in order to access their content in a well-defined manner on a queue in a different queue family. Resources shared with external APIs or instances using external memory must also explicitly manage ownership transfers between local and external queue= s (or equivalent constructs in external APIs) regardless of the VkSharingMode specified when creating them. The special queue family index VK_QUEUE_FAMILY_EXTERNAL repres= ents any queue external to the resource=E2=80=99s current Vulkan instance, as long a= s the queue uses the same underlying physical device or device group and uses the same driver version as the resource=E2=80=99s VkDevi= ce, as indicated by VkPhysicalDeviceIDProperties= ::deviceUUID and VkPhysicalDeviceIDProperties::drive= rUUID. The special queue family index VK_QUEUE_FAMILY_FOREIGN_EXT rep= resents any queue external to the resource=E2=80=99s current Vulkan instance, regar= dless of the queue=E2=80=99s underlying physical device or driver version. This includes, for example, queues for fixed-function image processing devices, media codec devices, and display devices, as well as all queues that use the same underlying physical device (or device group) and driver version as the resource=E2=80=99s VkDevice. If memory dependencies are correctly expressed between uses of such a resource between two queues in different families, but no ownership transfe= r is defined, the contents of that resource are undefined for any read accesses performed by the second queue family.

Note

If an application does not need the contents of a resource to remain val= id when transferring from one queue family to another, then the ownership transfer should be skipped.

Note

Applications should expect transfers to/from VK_QUEUE_FAMILY_FOREIGN_EXT to be more expensive than transfer= s to/from VK_QUEUE_FAMILY_EXTERNAL_KHR.

A queue family ownership transfer consists of two distinct parts:

  1. Release exclusive ownership from the source queue family

  2. Acquire exclusive ownership for the destination queue family

An application must ensure that these = operations occur in the correct order by defining an execution dependency between them, e.g. using a semaphore.

A release ope= ration is used to release exclusive ownership of a range of a buffer or image subresource range. A release operation is defined by executing a buffer memory barrier (for a buffer range) or an image memory barrier (for an image subresource range), on a queue from the source qu= eue family. The srcQueueFamilyIndex parameter of the barrier must be set to the source queue family index, and the dstQueueFamilyIndex paramet= er to the destination queue family index. dstStageMask is ignored for such a barrier, such that no visib= ility operation is executed - the value of this mask does not affect the validity of the barrier. The release operation happens-after the availability operation.

An acquire op= eration is used to acquire exclusive ownership of a range of a buffer or image subresource range. An acquire operation is defined by executing a buffer memory barrier (for a buffer range) or an image memory barrier (for an image subresource range), on a queue from the destinati= on queue family. The buffer range or image subresource range specified in an acquire operation must match exactly that of a pr= evious release operation. The srcQueueFamilyIndex parameter of the barrier must be set to the source queue family index, and the dstQueueFamilyIndex paramet= er to the destination queue family index. srcStageMask is ignored for such a barrier, such that no avail= ability operation is executed - the value of this mask does not affect the validity of the barrier. The acquire operation happens-before the visibility operation.

Note

Whilst it is not invalid to provide destination or source access masks f= or memory barriers used for release or acquire operations, respectively, they have no practical effect. Access after a release operation has undefined results, and so visibility for those accesses has no practical effect. Similarly, write access before an acquire operation will produce undefined results for future access, so availability of those writes has no practical use. In an earlier version of the specification, these were required to match on both sides - but this was subsequently relaxed. These masks should be set to 0.

If the transfer is via an image memory barrier, and an image layout transition is desired, then the values of oldLayout and newLayout in the release memory barrier must be equal to v= alues of oldLayout and newLayout in the acquire memory barrier. Although the image layout transition is submitted twice, it will only be executed once. A layout transition specified in this way happens-after the release operation and happens-before the acquire operation.

If the values of srcQueueFamilyIndex and dstQueueFami= lyIndex are equal, no ownership transfer is performed, and the barrier operates as if they were both set to VK_QUEUE_FAMILY_IGNORED.

Queue family ownership transfers may p= erform read and write accesses on all memory bound to the image subresource or buffer range, so applications must ensure that all memory writes have been made available before a queue family ownership transfer is executed. Available memory is automatically made visible to queue family release and acquire operations, and writes performed by those operations are automatically made available.

Once a queue family has acquired ownership of a buffer range or image subresource range of an VK_SHARING_MODE_EXCLUSIVE resource, it= s contents are undefined to other queue families unless ownership is transferred. The contents of any portion of another resource which aliases memory that i= s bound to the transferred buffer or image subresource range are undefined after a release or acquire operation.

6.8. Wait Idle Operations

To wait on the host for the completion of outstanding queue operations f= or a given queue, call:

VkResult vkQueueWa=
itIdle(
    VkQueue                                     queue);
  • queue is the queue on which to wait.

vkQueueWaitIdle is equivalent to submitting a fence to a qu= eue and waiting with an infinite timeout for that fence to signal.

Valid Usage (Implicit)
  • queue <= strong class=3D"purple">must be a valid VkQueue handl= e

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

To wait on the host for the completion of outstanding queue operations f= or all queues on a given logical device, call:

VkResult vkDeviceW=
aitIdle(
    VkDevice                                    device);
  • device is the logical device to idle.

vkDeviceWaitIdle is equivalent to calling vkQueueWait= Idle for all queues owned by device.

Valid Usage (Implicit)
  • device must be a valid VkDevice h= andle

Host Synchronization
  • Host access to all VkQueue objects created from devic= e must be externally synchronized<= /p>

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

6.9. Host Write Ordering = Guarantees

When batches of command buffers are submitted to a queue via vkQueueSubmit, it defines a memory dependency with prior= host operations, and execution of command buffers submitted to the queue.

The first synchronization scope= is defined by the host execution model, but includes execution of vkQueueSubmit on the host and anything that happened-bef= ore it.

The first access scope includes all host writes to mappable device memory that are either coherent= , or have been flushed with vkFlushMappedMemoryRan= ges.

The second access scope includes all memory access performed by the device.

6.10. Synchronization and Multiple = Physical Devices

If a logical device includes more than one physical device, then fences, semaphores, and events all still have a single instance of the signaled state.

A fence becomes signaled when all physical devices complete the necessar= y queue operations.

Semaphore wait and signal operations all include a device index that is = the sole physical device that performs the operation. These indices are provided in the VkDeviceGroupSub= mitInfo and VkDeviceGroupBindSparseInfo structures. Semaphores are not exclusively owned by any physical device. For example, a semaphore can be signaled by one physical device and then waited on by a different physical device.

An event can only be waited on by the = same physical device that signaled it (or the host).

7. Render Pass

A render pass represents a collection of attachments, subpasses= , and dependencies between the subpasses, and describes how the attachments are used over the course of the subpasses. The use of a render pass in a command buffer is a render pass instance<= /em>.

Render passes are represented by VkRenderPass handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkRenderPass)

An attachment description describes the properties of an attach= ment including its format, sample count, and how its contents are treated at the beginning and end of each render pass instance.

A subpass represents a phase of rendering that reads and writes= a subset of the attachments in a render pass. Rendering commands are recorded into a particular subpass of a render pass instance.

A subpass description describes the subset of attachments that = is involved in the execution of a subpass. Each subpass can read from some attachmen= ts as input attachments, write to some as color attachments or depth/stencil attachments= , and perform multisample resolve operations to resolve attachments. A subpass description can also include a = set of preserve attachments, which are attachments that are not read or written by the subpass but whose contents must be preserved throughout the= subpass.

A subpass uses an attachment if the attachment is a color, dept= h/stencil, resolve, or input attachment for that subpass (as determined by the pColorAttachments, pDepthStencilAttachment, pResolveAttachments, and pInputAttachments member= s of VkSubpassDescription, respectively). A subpass does not use an attachment if that attachment is preserved by the subpass. The first use of an attachment is in the lowest numbered subpass t= hat uses that attachment. Similarly, the last use of an attachment is in the highest numbere= d subpass that uses that attachment.

The subpasses in a render pass all render to the same dimensions, and fragments for pixel (x,y,layer) in one subpass can= only read attachment contents written by previous subpasses at that same (x,y,layer) location.

Note

By describing a complete set of subpasses in advance, render passes prov= ide the implementation an opportunity to optimize the storage and transfer of attachment data between subpasses.

In practice, this means that subpasses with a simple framebuffer-space dependency may be merged into a single ti= led rendering pass, keeping the attachment data on-chip for the duration of a render pass instance. However, it is also quite common for a render pass to only contain a single subpass.

Subpass dependencies describe exe= cution and memory dependencies between subpasses.

A subpass dependency chain is a sequence of subpass dependencie= s in a render pass, where the source subpass of each subpass dependency (after the first) equals the destination subpass of the previous dependency.

Execution of subpasses may overlap or = execute out of order with regards to other subpasses, unless otherwise enforced by an execution dependency. Each subpass only respects submission order for commands recorded in the same subpass, and the vkCmdBeginRenderPass and vkCm= dEndRenderPass commands that delimit the render pass - commands within other subpasses are not included. This affects most other implicit ordering guarantees.

A render pass describes the structure of subpasses and attachments independent of any specific image views for the attachments. The specific image views that will be used for the attachments, and their dimensions, are specified in VkFramebuffer objects. Framebuffers are created with respect to a specific render pass that the framebuffer is compatible with (see Render Pass Compatibility). Collectively, a render pass and a framebuffer define the complete render target state for one or more subpasses as well as the algorithmic dependencies between the subpasses.

The various pipeline stages of the drawing commands for a given subpass = may execute concurrently and/or out of order, both within and across drawing commands, whilst still respecting pi= peline order. However for a given (x,y,layer,sample) sample location, certain per-sample operations are performed in rasterization order.

7.1. Render Pass Creation

To create a render pass, call:

VkResult vkCreateR=
enderPass(
    VkDevice                                    device,
    const VkRenderPassCreateInfo*         =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkRenderPass*                               pRenderPass);
  • device is the logical device that creates the render pass.<= /p>

  • pCreateInfo is a pointer to an instance of the VkRenderPassCreateInfo structure that describes= the parameters of the render pass.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pRenderPass points to a VkRenderPass hand= le in which the resulting render pass object is returned.

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • pCrea= teInfo must be a valid pointer to = a valid VkRenderPassCreateInfo structure

  • If pAl= locator is not NULL, pAllocator must be a valid pointer to a valid VkAllocati= onCallbacks structure

  • pRend= erPass must be a valid pointer to = a VkRenderPass handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkRenderPassCreateInfo structure is defined as:

typedef struct VkRenderPassCrea=
teInfo {
    VkStructureType                   sType;
    const void*                       pNext;
    VkRenderPassCreateFlags           flags;
    uint32_t                          attachmentCount;
    const VkAttachmentDescription*    pAtt=
achments;
    uint32_t                          subpassCount;
    const VkSubpassDescription*       pSub=
passes;
    uint32_t                          dependencyCount;
    const VkSubpassDependency*        pDep=
endencies;
} VkRenderPassCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • attachmentCount is the number of attachments used by this r= ender pass, or zero indicating no attachments. Attachments are referred to by zero-based indices in the range [0,attachmentCount).

  • pAttachments points to an array of attachmentCount number of VkAttachmentDescription structures describing = properties of the attachments, or NULL if attachmentCount is zero.<= /p>

  • subpassCount is the number of subpasses to create for this = render pass. Subpasses are referred to by zero-based indices in the range [0,subpassCount). A render pass must have at least one subp= ass.

  • pSubpasses points to an array of subpassCount = number of VkSubpassDescription structures describing proper= ties of the subpasses.

  • dependencyCount is the number of dependencies between pairs= of subpasses, or zero indicating no dependencies.

  • pDependencies points to an array of dependencyCount number of VkSubpassDependency structures describing depen= dencies between pairs of subpasses, or NULL if dependencyCount is= zero.

Valid Usage
  • If any two subpasses operate on attachments with overlapping ranges of the same VkDeviceMemory object, and at least one subpass write= s to that area of VkDeviceMemory, a subpass dependency must be included (either directly or via some intermediate subpasses) between them

  • If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments or pDepthStencilAttachment, o= r the attachment indexed by any element of pPreserveAttachments in a= ny element of pSubpasses is bound to a range of a VkDeviceMemory object that overlaps with any other attachment = in any subpass (including the same subpass), the VkAttachmentDescription structures describing them must include VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT in flags<= /p>

  • If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments or pDepthStencilAttachment, o= r any element of pPreserveAttachments in any element of pSubpa= sses is not VK_ATTACHMENT_UNUSED, it must<= /strong> be less than attachmentCount

  • The value of each element of the pPreserveAttachments member i= n each element of pSubpasses must not be VK_ATTACHMENT_UNUSED

  • For any member of pAttachments with a loadOp equa= l to VK_ATTACHMENT_LOAD_OP_CLEAR, the first use of that attachment must not specify a layout eq= ual to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL.

  • For any member of pAttachments with a loadOp equa= l to VK_ATTACHMENT_LOAD_OP_CLEAR, the first use of that attachment must not specify a layout eq= ual to VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL.

  • For any member of pAttachments with a stencilLoadOp equal to VK_ATTACHMENT_LOAD_OP_CLEAR, the first use of that attachment must not specify a layout eq= ual to VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL.

  • If the pNext chain includes an instance of VkRenderPassInputAttachmentAsp= ectCreateInfo, the subpass member of each element of its pAspectReferences member must be less than subpassCount

  • If the pNext chain includes an instance of VkRenderPassInputAttachmentAsp= ectCreateInfo, the inputAttachmentIndex member of each element of its pAspectReferences member must be less than the value of inputAttachmentCount in the member of pSubpasses = identified by its subpass member

  • If the pNext chain includes an instance of VkRenderPassInputAttachmentAsp= ectCreateInfo, the aspectMask member of any element of pAspectReferences must only include aspects that are present in images of the format of the input attachment specified by the subpass and inputAttachment<= /code> of the same element of pAspectReferences

  • If the pNext chain includes an instance of VkRenderPassMultiviewCreateInfo, and i= ts subpassCount member is not zero, that member must be equal to= the value of subpassCount

  • If the pNext chain includes an instance of VkRenderPassMultiviewCreateInfo, if it= s dependencyCount member is not zero, it must be equal to <= code>dependencyCount

  • If the pNext chain includes an instance of VkRenderPassMultiviewCreateInfo, for e= ach non-zero element of pViewOffsets, the srcSubpass and dstSubpass= members of pDependencies at the same index must<= /strong> not be equal

  • For any element of pDependencies, if the srcSubpass is not VK_SUBPASS_EXTERNAL, all stage flags included in the srcStageMask member of that dependency must be a pipeline stage supported by the pipeline identified by the pipelineBindPoint member of the source subpa= ss.

  • For any element of pDependencies, if the dstSubpass is not VK_SUBPASS_EXTERNAL, all stage flags included in the dstStageMask member of that dependency must be a pipeline stage supported by the pipeline identified by the pipelineBindPoint member of the source subpa= ss.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_RENDER_= PASS_CREATE_INFO

  • Each pNext<= /code> member of any structure (including this one) in the pNext chain must be either NULL= or a pointer to a valid instance of VkRenderPassInputAttachmentAspectCreateInfo or VkRenderPassMultiviewCreateInfo

  • Each sType= member in the pNext chain mus= t be unique

  • flags= must be 0

  • If attachmentCount is not 0, pAttachments = must be a valid pointer to an array of attachmentCount valid VkAttachmentDescription struc= tures

  • pS= ubpasses must be a valid pointer t= o an array of subpassCount valid VkSubpassDescription structures

  • If dependencyCount is not 0, pDependencies must be a valid pointer to an array of = dependencyCount valid VkSubpassDependency structu= res

  • subpassCount must be greater tha= n 0

typedef VkFlags VkRenderPassCreateFlags;

VkRenderPassCreateFlags is a bitmask type for setting a mas= k, but is currently reserved for future use.

If the VkRenderPassCreateInfo::pNext chain inc= ludes a VkRenderPassMultiviewCreateInfo structure, then that structure includes an array of view masks, view offsets, and correlation masks for th= e render pass.

The VkRenderPassMultiviewCreateInfo structure is defined as= :

typedef struct VkRenderPassMult=
iviewCreateInfo {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           subpassCount;
    const uint32_t*    pViewMasks;
    uint32_t           dependencyCount;
    const int32_t*     pViewOffsets;
    uint32_t           correlationMaskCount;
    const uint32_t*    pCorrelationMasks;
} VkRenderPassMultiviewCreateInfo;

or the equivalent

typedef VkRenderPassMultiviewCreateInfo VkRenderPassMultiviewC=
reateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • subpassCount is zero or is the number of subpasses in the r= ender pass.

  • pViewMasks points to an array of subpassCount = number of view masks, where each mask is a bitfield of view indices describing which views rendering is broadcast to in each subpass, when multiview is enabled. If subpassCount is zero, each view mask is treated as zero.

  • dependencyCount is zero or the number of dependencies in th= e render pass.

  • pViewOffsets points to an array of dependencyCount view offsets, one for each dependency. If dependencyCount is zero, each dependency=E2=80=99s view off= set is treated as zero. Each view offset controls which views in the source subpass the views in the destination subpass depend on.

  • correlationMaskCount is zero or a number of correlation mas= ks.

  • pCorrelationMasks is an array of view masks indicating sets= of views that may be more efficient to rende= r concurrently.

When a subpass uses a non-zero view mask, multiview functionali= ty is considered to be enabled. Multiview is all-or-nothing for a render pass - that is, either all subpasses must have a non-zero view mask = (though some subpasses may have only one view) or all must be zero. Multiview causes all drawing and clear commands in the subpass to behave as if they were broadcast to each view, where a view is represented by one layer of the framebuffer attachments. All draws and clears are broadcast to each view index whose bit is= set in the view mask. The view index is provided in the ViewIndex shader input varia= ble, and color, depth/stencil, and input attachments all read/write the layer of the framebuffer corresponding to the view index.

If the view mask is zero for all subpasses, multiview is considered to b= e disabled and all drawing commands execute normally, without this additional broadcasting.

Some implementations may not support m= ultiview in conjunction with geometry shaders or tessellation shaders.

When multiview is enabled, the VK_DEPENDENCY_VIEW_LOCAL_BIT= bit in a dependency can be used to express a view-= local dependency, meaning that each view in the destination subpass depends on a single view in the source subpass. Unlike pipeline barriers, a subpass dependency can= potentially have a different view mask in the source subpass and the destination subpass. If the dependency is view-local, then each view (dstView= ) in the destination subpass depends on the view dstView +=20 pViewOffsets[dependency] in the source subpass. If there is not such a view in the source subpass, then this dependency doe= s not affect that view in the destination subpass. If the dependency is not view-local, then all views in the destination subpass depend on all views in the source subpass, and the view offset is ignored. A non-zero view offset is not allowed in a self-dependency.

The elements of pCorrelationMasks are a set of masks of vie= ws indicating that views in the same mask may exhibit spatial coherency between the views, making it more efficient to render them concurrently. Correlation masks must not have a functio= nal effect on the results of the multiview rendering.

When multiview is enabled, at the beginning of each subpass all non-rend= er pass state is undefined. In particular, each time vkCmdBeginRenderPass or vkCmdNextSubpass is called the graphics pipeline must be bound, any relevant descriptor sets or vertex/index buffers m= ust be bound, and any relevant dynamic state or push constants must be set before they are used.

A multiview subpass can declare that i= ts shaders will write per-view attributes for all views in a single invocation, by setting the VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX bit in the = subpass description. The only supported per-view attributes are position and viewport mask, and per-view position and viewport masks are written to output array variables decorated with PositionPerViewNV and ViewportMaskPerView= NV, respectively. If VK_NV_viewport_array2 is not sup= ported and enabled, ViewportMaskPerViewNV must n= ot be used. Values written to elements of PositionPerViewNV and ViewportMaskPerViewNV must n= ot depend on the ViewIndex. The shader must also write to an output v= ariable decorated with Position, and the value written to Position must equal the value written to PositionPerViewNV[ViewIndex]. Similarly, if ViewportMaskPerViewNV is written to then the sha= der must also write to an output variable decorated with ViewportMaskNV= , and the value written to ViewportMaskNV must<= /strong> equal the value written to ViewportMaskPerViewNV[ViewIndex]. Implementations will either use values taken from Position and ViewportMaskNV and invoke the shader once for each view, or wi= ll use values taken from PositionPerViewNV and ViewportMaskPerV= iewNV and invoke the shader fewer times. The values written to Position and ViewportMaskNV= must not depend on the values written to PositionPerViewNV and ViewportMaskPerViewNV, or vice versa (to allow compilers to el= iminate the unused outputs). All attributes that do not have *PerViewNV counterparts must not depend on ViewIndex.

Per-view attributes are all-or-nothing for a subpass. That is, all pipelines compiled against a subpass that includes the VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX bit must write per-view attributes to the *PerViewNV[] shader outputs, in add= ition to the non-per-view (e.g. Position) outputs. Pipelines compiled against a subpass that does not include this bit must not include the *PerViewNV[] outputs in their interfaces.

Valid Usage (Implicit)

The VkAttachmentDescription structure is defined as:

typedef struct VkAttachmentDesc=
ription {
    VkAttachmentDescriptionFlags    flags;
    VkFormat                        format;
    VkSampleCountFlagBits           samples;
    VkAttachmentLoadOp              loadOp;
    VkAttachmentStoreOp             storeOp;
    VkAttachmentLoadOp              stencilLoadOp;
    VkAttachmentStoreOp             stencilStoreOp;
    VkImageLayout                   initialLayout;
    VkImageLayout                   finalLayout;
} VkAttachmentDescription;

If the attachment uses a color format, then loadOp and storeOp are used, and stencilLoadOp and stencilStoreOp ar= e ignored. If the format has depth and/or stencil components, loadOp and storeOp apply only to the depth data, while stencilLoadO= p and stencilStoreOp define how the stencil data is handled. loadOp and stencilLoadOp define the load oper= ations that execute as part of the first subpass that uses the attachment. storeOp and stencilStoreOp define the store o= perations that execute as part of the last subpass that uses the attachment.

The load operation for each sample in an attachment happens-before any recorded command which accesses the sample in the first subpass where the attachment is used. Load operations for attachments with a depth/stencil format execute in the VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT pipeline stage. Load operations for attachments with a color format execute in the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage.<= /p>

The store operation for each sample in an attachment happens-after any recorded command which accesses the sample in the last subpass where the attachment is used. Store operations for attachments with a depth/stencil format execute in the VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT pipeline stage. Store operations for attachments with a color format execute in the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage.<= /p>

If an attachment is not used by any subpass, then loadOp, storeOp, stencilStoreOp, and stencilLoadOp<= /code> are ignored, and the attachment=E2=80=99s memory contents will not be modified by execut= ion of a render pass instance.

The load and store operations apply on the first and last use of each vi= ew in the render pass, respectively. If a view index of an attachment is not included in the view mask in any subpass that uses it, then the load and store operations are ignored, and the attachment=E2=80=99s memory contents will not be modified by execution = of a render pass instance.

During a render pass instance, input/color attachments with color format= s that have a component size of 8, 16, or 32 bits mu= st be represented in the attachment=E2=80=99s format throughout the instance. Attachments with other floating- or fixed-point color formats, or with dept= h components may be represented in a format= with a precision higher than the attachment format, but must be represente= d with the same range. When such a component is loaded via the loadOp, it will be con= verted into an implementation-dependent format used by the render pass. Such components must be converted from th= e render pass format, to the format of the attachment, before they are resolved or stored at the end of = a render pass instance via storeOp. Conversions occur as described in Numeric Representation and Computation and Fixed-Point Data Conversions.

If flags includes VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS= _BIT, then the attachment is treated as if it shares physical memory with another attachment in the same render pass. This information limits the ability of the implementation to reorder certai= n operations (like layout transitions and the loadOp) such that = it is not improperly reordered against other uses of the same physical memory via a different attachment. This is described in more detail below.

Valid Usage
  • finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED

Valid Usage (Implicit)

To specify which aspects of an input attachment can be read add a VkRenderPassInputAttachmentAsp= ectCreateInfo structure to the pNext chain of the VkRenderPassCreateI= nfo structure:

The VkRenderPassInputAttachmentAspectCreateInfo structure i= s defined as:

typedef struct VkRenderPassInpu=
tAttachmentAspectCreateInfo {
    VkStructureType                            sType;
    const void*                                pNext;
    uint32_t                                   aspectReferenceCount;
    const VkInputAttachmentAspectReference=
*    pAspectReferences;
} VkRenderPassInputAttachmentAspectCreateInfo;

or the equivalent

typedef VkRenderPassInputAttachmentAspectCreateInfo VkRenderPa=
ssInputAttachmentAspectCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • aspectReferenceCount is the number of elements in the pAspectReferences array.

  • pAspectReferences points to an array of aspectReferen= ceCount number of VkInputAttachmentAspectReferenc= e structures describing which aspect(s) can be accessed for a giv= en input attachment within a given subpass.

Valid Usage (Implicit)

The VkInputAttachmentAspectReference structure specifies an= aspect mask for a specific input attachment of a specific subpass in the render pass.

subpass and inputAttachmentIndex index into th= e render pass as:

pCreateInfo::pSubpasses[subpass].= pInputAttachments[inputAttachmentIndex]

typedef struct VkInputAttachmen=
tAspectReference {
    uint32_t              subpass;
    uint32_t              inputAttachmentIndex;
    VkImageAspectFlags    aspectMask;
} VkInputAttachmentAspectReference;

or the equivalent

typedef VkInputAttachmentAspectReference VkInputAttachmentAspe=
ctReferenceKHR;
  • subpass is an index into the pSubpasses array = of the parent VkRenderPassCreateInfo structure.

  • inputAttachmentIndex is an index into the pInputAttac= hments of the specified subpass.

  • aspectMask is a mask of which aspect(s) can be accessed within the specified subpass.

Valid Usage
  • aspectMask must not include = VK_IMAGE_ASPECT_METADATA_BIT

Valid Usage (Implicit)
editing-note

TODO (Jon) - it=E2=80=99s unclear whether the following two paragraphs a= re intended to apply to VkAttachmentDescription, one of th= e extension structures described immediately above, or something else. The following description of VkAttachmentD= escriptionFlagBits should probably be moved up to near VkAttachmentDescripti= on.

An application must only access the sp= ecified aspect(s).

An application can access any aspect o= f an input attachment that does not have a specified aspect mask.

Bits which can be set in VkAttachmentDescription::flags describing additional properties of the attachment are:

typedef enum VkAttachmentDescri=
ptionFlagBits {
    VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT =3D 0x00000=
001,
} VkAttachmentDescriptionFlagBits;
  • VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT specifies that the attachment aliases the same device memory as other attachments.

typedef VkFlags VkAttachmentDescriptionFlags;

VkAttachmentDescriptionFlags is a bitmask type for setting = a mask of zero or more VkAttachmentDescriptionFlagBi= ts.

Possible values of VkAttachmentDescription:= :loadOp and stencilLoadOp, specifying how the contents of the attachment a= re treated, are:

typedef enum VkAttachmentLoadOp=
 {
    VK_ATTACHMENT_LOAD_OP_LOAD =3D 0,
    VK_ATTACHMENT_LOAD_OP_CLEAR =3D 1,
    VK_ATTACHMENT_LOAD_OP_DONT_CARE =3D 2,
} VkAttachmentLoadOp;
  • VK_ATTACHMENT_LOAD_OP_LOAD specifies that the previous cont= ents of the image within the render area will be preserved. For attachments with a depth/stencil format, this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT. For attachments with a color format, this uses the access type VK_ACCESS_COLOR_ATTACHMENT_READ_BIT.

  • VK_ATTACHMENT_LOAD_OP_CLEAR specifies that the contents wit= hin the render area will be cleared to a uniform value, which is specified when a render pass instance is begun. For attachments with a depth/stencil format, this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. For attachments with a color format, this uses the access type VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.

  • VK_ATTACHMENT_LOAD_OP_DONT_CARE specifies that the previous contents within the area need not be preserved; the contents of the attachment will be undefined inside the render area. For attachments with a depth/stencil format, this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. For attachments with a color format, this uses the access type VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.

Possible values of VkAttachmentDescription:= :storeOp and stencilStoreOp, specifying how the contents of the attachment = are treated, are:

typedef enum VkAttachmentStoreO=
p {
    VK_ATTACHMENT_STORE_OP_STORE =3D 0,
    VK_ATTACHMENT_STORE_OP_DONT_CARE =3D 1,
} VkAttachmentStoreOp;
  • VK_ATTACHMENT_STORE_OP_STORE specifies the contents generat= ed during the render pass and within the render area are written to memory. For attachments with a depth/stencil format, this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. For attachments with a color format, this uses the access type VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.

  • VK_ATTACHMENT_STORE_OP_DONT_CARE specifies the contents wit= hin the render area are not needed after rendering, and ma= y be discarded; the contents of the attachment will be undefined inside the render area. For attachments with a depth/stencil format, this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. For attachments with a color format, this uses the access type VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.

editing-note

TODO (Jon) - the following text may need to be moved back to combine wit= h vkCreateRenderPass above for automatic ref page gen= eration.

If a render pass uses multiple attachments that alias the same device memory, those attachments must each inclu= de the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT bit in their attachmen= t description flags. Attachments aliasing the same memory occurs in multiple ways:

  • Multiple attachments being assigned the same image view as part of framebuffer creation.

  • Attachments using distinct image views that correspond to the same image subresource of an image.

  • Attachments using views of distinct image subresources which are bound to overlapping memory ranges.

Note

Render passes must include subpass dep= endencies (either directly or via a subpass dependency chain) between any two subpasses that operate on the sam= e attachment or aliasing attachments and those subpass dependencies must include execution and memory dependencies separating uses of the aliases, i= f at least one of those subpasses writes to one of the aliases. These dependencies must not include the <= code>VK_DEPENDENCY_BY_REGION_BIT if the aliases are views of distinct image subresources which overlap in memory.

Multiple attachments that alias the same memory must not be used in a single subpass. A given attachment index must not be used= multiple times in a single subpass, with one exception: two subpass attachments can use the same attachment index if at least one use is as an input attachment and neither use is as a resolve or preserve attachment. In other words, the same view can be used= simultaneously as an input and color or depth/stencil attachment, but must not be used as multiple color or depth/stencil attachments nor as resolve or preserve attachments. The precise set of valid scenarios is described in more detail below.

If a set of attachments alias each other, then all except the first to b= e used in the render pass must use an initialLayout of VK_IMAGE_LAYOUT_UNDEFINED, since the earlier uses of the other= aliases make their contents undefined. Once an alias has been used and a different alias has been used after it, the first alias must not be used in any l= ater subpasses. However, an application can assign the sa= me image view to multiple aliasing attachment indices, which allows that image view to be used multiple times even if other aliases are used in between.

Note

Once an attachment needs the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_B= IT bit, there should be no additional cost o= f introducing additional aliases, and using these additional aliases may al= low more efficient clearing of the attachments on multiple uses via VK_ATTACHMENT_LOAD_OP_CLEAR.<= /p>

The VkSubpassDescription structure is defined as:

typedef struct VkSubpassDescrip=
tion {
    VkSubpassDescriptionFlags       flags;
    VkPipelineBindPoint             pipelineBindPoint;
    uint32_t                        inputAttachmentCount;
    const VkAttachmentReference*    pInput=
Attachments;
    uint32_t                        colorAttachmentCount;
    const VkAttachmentReference*    pColor=
Attachments;
    const VkAttachmentReference*    pResol=
veAttachments;
    const VkAttachmentReference*    pDepth=
StencilAttachment;
    uint32_t                        preserveAttachmentCount;
    const uint32_t*                 pPrese=
rveAttachments;
} VkSubpassDescription;
  • flags is a bitmask of VkSubpa= ssDescriptionFlagBits specifying usage of the subpass.

  • pipelineBindPoint is a VkPipelineBindP= oint value specifying whether this is a compute or graphics subpass. Currently, only graphics subpasses are supported.

  • inputAttachmentCount is the number of input attachments.

  • pInputAttachments is an array of VkA= ttachmentReference structures (defined below) that lists which of the render pass=E2=80=99s attachments can be read in the fragment s= hader stage during the subpass, and what layout each attachment will be in during the subpass. Each element of the array corresponds to an input attachment unit number in the shader, i.e. if the shader declares an input variable layout(input_attachment_index=3DX, set=3DY, binding=3DZ) then = it uses the attachment provided in pInputAttachments[X]. Input attachments must also be bound to t= he pipeline with a descriptor set, with the input attachment descriptor written in the location (set=3DY, binding=3DZ). Fragment shaders can use subpass input va= riables to access the contents of an input attachment at the fragment=E2=80=99s (x, y, layer) framebuffer coordinates.

  • colorAttachmentCount is the number of color attachments.

  • pColorAttachments is an array of colorAttachmentCount= VkAttachmentReference structures that lists whic= h of the render pass=E2=80=99s attachments will be used as color attachments in the subpass= , and what layout each attachment will be in during the subpass. Each element of the array corresponds to a fragment shader output location, i.e. if the shader declared an output variable layout(location=3DX) then it uses the attachment provided in pColorAttachments[X].

  • pResolveAttachments is NULL or an array of colorAttachmentCount VkAttachmentRefere= nce structures that lists which of the render pass=E2=80=99s attachments are resolved to at the= end of the subpass, and what layout each attachment will be in during the multisample resolve operation. If pResolveAttachments is not NULL, each of its e= lements corresponds to a color attachment (the element in pColorAttachments at the same index), and a multisample resolv= e operation is defined for each attachment. At the end of each subpass, multisample resolve operations read the subpass=E2=80=99s color attachments, and resolve the samples for each pixel= to the same pixel location in the corresponding resolve attachments, unless the resolve attachment index is VK_ATTACHMENT_UNUSED. If the first use of an attachment in a render pass is as a resolve attachment, then the loadOp is effectively ignored as the reso= lve is guaranteed to overwrite all pixels in the render area.

  • pDepthStencilAttachment is a pointer to a VkAttachmentReference specifying which attachmen= t will be used for depth/stencil data and the layout it will be in during the subpass. Setting the attachment index to VK_ATTACHMENT_UNUSED or leavin= g this pointer as NULL indicates that no depth/stencil attachmen= t will be used in the subpass.

  • preserveAttachmentCount is the number of preserved attachme= nts.

  • pPreserveAttachments is an array of preserveAttachmen= tCount render pass attachment indices describing the attachments that are not used by a subpass, but whose contents must be preserved throughout the subpass.

The contents of an attachment within the render area become undefined at= the start of a subpass S if all of the following conditions ar= e true:

  • The attachment is used as a color, depth/stencil, or resolve attachment in any subpass in the render pass.

  • There is a subpass S1 that uses or preserves= the attachment, and a subpass dependency from S1 to S.

  • The attachment is not used or preserved in subpass S.

Once the contents of an attachment become undefined in subpass S= , they remain undefined for subpasses in subpass dependency chains starting with subpass S until they are written again. However, they remain valid for subpasses in other subpass dependency chains starting with subpass S1 if those subpasses use= or preserve the attachment.

Valid Usage
  • pipelineBindPoint must be VK_PIPELINE_BIND_POINT_GRAPHICS

  • colorAttachmentCount must be= less than or equal to VkPhysicalDeviceLimits::maxColorAttachments

  • If the first use of an attachment in this render pass is as an input attachment, and the attachment is not also used as a color or depth/stencil attachment in the same subpass, then loadOp must not be VK_ATTACHMENT_LOAD_OP_CLEAR

  • If pResolveAttachments is not NULL, for each reso= lve attachment that does not have the value VK_ATTACHMENT_UNUSED, the corresponding color attachment must not h= ave the value VK_ATTACHMENT_UNUSED

  • If pResolveAttachments is not NULL, the sample co= unt of each element of pColorAttachments must be anything other than VK_SAMPLE_COUNT_1_BIT

  • Each element of pResolveAttachments m= ust have a sample count of VK_SAMPLE_COUNT_1_BIT

  • Each element of pResolveAttachments m= ust have the same VkFormat as its corresponding color attachment

  • All attachments in pColorAttachments that are not VK_ATTACHMENT_UNUSED must ha= ve the same sample count

  • All attachments in pColorAttachments that are not VK_ATTACHMENT_UNUSED must ha= ve a sample count that is smaller than or equal to the sample count of pDepthStencilAttachment i= f it is not VK_ATTACHMENT_UNUSED

  • If any input attachments are VK_ATTACHMENT_UNUSED, then any pipelines bound during the subpass must n= ot access those input attachments from the fragment shader

  • The attachment member of each element of pPreserveAttachments must no= t be VK_ATTACHMENT_UNUSED

  • Each element of pPreserveAttachments = must not also be an element of any other member of the subpass description

  • If any attachment is used as both an input attachment and a color or depth/stencil attachment, then each use must use the same layout

  • If flags includes VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX, it must also include VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX.

Valid Usage (Implicit)
  • flags must be a valid combination of VkSubpassDescriptionFlagBits values

  • pipelineBindPoint must be a val= id VkPipelineBindPoint value

  • If = inputAttachmentCount is not 0, pInputAttach= ments must be a valid pointer to a= n array of inputAttachmentCount valid VkAttachmentRefere= nce structures

  • If = colorAttachmentCount is not 0, pColorAttach= ments must be a valid pointer to a= n array of colorAttachmentCount valid VkAttachmentRefere= nce structures

  • I= f colorAttachmentCount is not 0, and pResol= veAttachments is not NULL, pResolveAttachments must be a valid pointer to an array = of colorAttachmentCount valid VkAttachmentReference structures

  • If pDepthStencilAttachment is not NULL, = pDepthStencilAttachment must be a = valid pointer to a valid VkAttachmentReference structure

  • = If preserveAttachmentCount is not 0, pPrese= rveAttachments must be a valid poi= nter to an array of preserveAttachmentCount uint32_t values

Bits which can be set in VkSubpassDescription::flags, specifying usage of the subpass, are:

typedef enum VkSubpassDescripti=
onFlagBits {
    VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX =3D 0x00000001,
    VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX =3D 0x00000002,
} VkSubpassDescriptionFlagBits;
  • VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX specifie= s that shaders compiled for this subpass write the attributes for all views in a single invocation of each vertex processing stage. All pipelines compiled against a subpass that includes this bit must write per-view attributes to the *PerViewNV[] shader outputs, = in addition to the non-per-view (e.g. Position) outputs.

  • VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX spe= cifies that shaders compiled for this subpass use per-view positions which only differ in value in the x component. Per-view viewport mask can also be used.<= /p>

typedef VkFlags VkSubpassDescriptionFlags;

VkSubpassDescriptionFlags is a bitmask type for setting a m= ask of zero or more VkSubpassDescriptionFlagBits.

The VkAttachmentReference structure is defined as:

typedef struct VkAttachmentRefe=
rence {
    uint32_t         attachment;
    VkImageLayout    layout;
} VkAttachmentReference;
  • attachment is the index of the attachment of the render pas= s, and corresponds to the index of the corresponding element in the pAttachments array of the VkRenderPassCreateInfo = structure. If any color or depth/stencil attachments are VK_ATTACHMENT_UNUSED, then no writes occur for those attachmen= ts.

  • layout is a VkImageLayout value specifyi= ng the layout the attachment uses during the subpass.

Valid Usage
  • layout must not be VK_= IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED

Valid Usage (Implicit)

The VkSubpassDependency structure is defined as:

typedef struct VkSubpassDepende=
ncy {
    uint32_t                srcSubpass;
    uint32_t                dstSubpass;
    VkPipelineStageFlags    srcStageMask;
    VkPipelineStageFlags    dstStageMask;
    VkAccessFlags           srcAccessMask;
    VkAccessFlags           dstAccessMask;
    VkDependencyFlags       dependencyFlags;
} VkSubpassDependency;

If srcSubpass is equal to dstSubpass then the VkSubpassDependency describes a subpass self-dependency, and only constrains the pipeline barriers allowed with= in a subpass instance. Otherwise, when a render pass instance which includes a subpass dependency is submitted to a queue, it defines a memory dependency between the subpasses identified by srcSubpass and dstSubpass= .

If srcSubpass is equal to VK_SUBPASS_EXTERNAL,= the first synchronization scope includes commands that occur earlier in submission order than the vkCmdBeginRenderPass used to b= egin the render pass instance. Otherwise, the first set of commands includes all commands submitted as par= t of the subpass instance identified by srcSubpass and any load,= store or multisample resolve operations on attachments used in srcSubpass. In either case, the first synchronization scope is limited to operations on the pipeline stages determined by the source stage mask specified by srcStageMask.

If dstSubpass is equal to VK_SUBPASS_EXTERNAL,= the second synchronization scope includes commands that occur later in submission order than the vkCmdEndRenderPass used to end t= he render pass instance. Otherwise, the second set of commands includes all commands submitted as part of the subpass instance identified by dstSubpass and any = load, store or multisample resolve operations on attachments used in dstSubpass. In either case, the second synchronization scope is limited to operations o= n the pipeline stages determined by the destination stage mask specified by dstStageMask.

The first access scope i= s limited to access in the pipeline stages determined by the source stage mask specified by srcStageMask. It is also limited to access types in the sou= rce access mask specified by srcAccessMask.

The second access scope = is limited to access in the pipeline stages determined by the destination stage mask specified by dstStageMask. It is also limited to access types in the des= tination access mask specified by dstAccessMask.

The availability and visibility operations defined by a subpass dependency affect the execut= ion of image layout transitions within the render pass.

Note

For non-attachment resources, the memory dependency expressed by subpass dependency is nearly identical to that of a VkMemoryBarrie= r (with matching srcAccessMask/dstAccessMask parameters) = submitted as a part of a vkCmdPipelineBarrier (with matching srcStageMask/dstStageMask parameters). The only difference being that its scopes are limited to the identified subpasses rather than potentially affecting everything before and after.

For attachments however, subpass dependencies work more like an VkImageMemoryBarrier defined similarly to the VkMemoryBarrier above, the queue family indices set to VK_QUEUE_FAMILY_IGNORED= , and layouts as follows:

  • The equivalent to oldLayout is the attachment=E2=80=99s lay= out according to the subpass description for srcSubpass.

  • The equivalent to newLayout is the attachment=E2=80=99s lay= out according to the subpass description for dstSubpass.

Valid Usage
  • If srcSubpass is not VK_SUBPASS_EXTERNAL, s= rcStageMask must not include VK_PIPELINE_STAGE_= HOST_BIT

  • If dstSubpass is not VK_SUBPASS_EXTERNAL, d= stStageMask must not include VK_PIPELINE_STAGE_= HOST_BIT

  • If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the tessellation shaders feature is not enabled, srcStageMask = must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • If the tessellation shaders feature is not enabled, dstStageMask = must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • srcSubpass must be less than= or equal to dstSubpass, unless one of them is VK_SUBPASS_EXTERNAL, to avoid cyclic dependenci= es and ensure a valid execution order

  • srcSubpass and dstSubpass must not both be equal to VK_SUBPASS_EXTERNAL

  • If srcSubpass is equal to dstSubpass, srcSt= ageMask and dstStageMask must not set an= y bits that are not VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, or not one of the graphics pipeline stages

  • If srcSubpass is equal to dstSubpass and not all = of the stages in srcStageMask and dstStageMask are framebuffer-space stages, the logically latest pipeline stage in srcStageMask must b= e logically earlier than or equal to the logically earliest pipeline stage in dstStageMask

  • Any access flag included in srcAccessMask must be supported by one of the pipeline stages in srcStageMask, as specified in th= e table of supported access types.

  • Any access flag included in dstAccessMask must be supported by one of the pipeline stages in dstStageMask, as specified in th= e table of supported access types.

  • If dependencyFlags includes VK_DEPENDENCY_VIEW_LOCAL_BIT= , then both srcSubpass and dstSubpass must not equal VK_SUBPASS_EXTERNAL

  • If dependencyFlags includes VK_DEPENDENCY_VIEW_LOCAL_BIT= , then the render pass must have multiview = enabled

  • If srcSubpass equals dstSubpass and that subpass = has more than one bit set in the view mask, then dependencyFlags must include VK_DEPENDENCY_VIEW_LOCAL_BIT

Valid Usage (Implicit)

When multiview is enabled, the execution of the multiple views of one subpass may not occur simultaneously or e= ven back-to-back, and rather may be interleaved with the execution of other subpasses. The load and store operations apply to attachments on a per-view basis. For example, an attachment using VK_ATTACHMENT_LOAD_OP_CLEAR w= ill have each view cleared on first use, but the first use of one view may be temporally distant from the first use of another view.

Note

A good mental model for multiview is to think of a multiview subpass as = if it were a collection of individual (per-view) subpasses that are logically grouped together and described as a single multiview subpass in the API. Similarly, a multiview attachment can be thought of like several individual attachments that happen to be layers in a single image. A view-local dependency between two multiview subpasses acts like a set of one-to-one dependencies between corresponding pairs of per-view subpasses. A view-global dependency between two multiview subpasses acts like a set of N =C3=97 M dependencies between all pairs of per-= view subpasses in the source and destination. Thus, it is a more compact representation which also makes clear the commonality and reuse that is present between views in a subpass. This interpretation motivates the answers to questions like =E2=80=9Cwhen d= oes the load op apply=E2=80=9D - it is on the first use of each view of an attachme= nt, as if each view were a separate attachment.

editing-note

The following two alleged implicit dependencies are practically no-ops, = as the operations they describe are already guaranteed by semaphores and submission order (so they=E2=80=99re almost entirely no-ops on their own). The only reason they exist is because it simplifies reason= ing about where automatic layout transitions happen. Further rewrites of this chapter could potentially remove the need for these.

If there is no subpass dependency from VK_SUBPASS_EXTERNAL = to the first subpass that uses an attachment, then an implicit subpass dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is use= d in. The subpass dependency operates as if defined with the following parameters= :

VkSubpassDependency =
implicitDependency =3D {
    .srcSubpass =3D VK_SUBPASS_EXTERNAL;
    .dstSubpass =3D firstSubpass; // First subpass =
attachment is used in
    .srcStageMask =3D VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
    .dstStageMask =3D VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
    .srcAccessMask =3D 0;
    .dstAccessMask =3D VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
                     VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
                     VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
                     VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
                     VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
    .dependencyFlags =3D 0;
};

Similarly, if there is no subpass dependency from the last subpass that = uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit subpass dependency exists from the last subpass it is used in to VK_SUBPASS_EXTERNAL. The subpass dependency operates as if defined with the following parameters= :

VkSubpassDependency =
implicitDependency =3D {
    .srcSubpass =3D lastSubpass; // Last subpass at=
tachment is used in
    .dstSubpass =3D VK_SUBPASS_EXTERNAL;
    .srcStageMask =3D VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
    .dstStageMask =3D VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
    .srcAccessMask =3D VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
                     VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
                     VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
                     VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
                     VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
    .dstAccessMask =3D 0;
    .dependencyFlags =3D 0;
};

As subpasses may overlap or execute ou= t of order with regards to other subpasses unless a subpass dependency chain describes otherwise, the layout transitions required between subpasses cannot be known to an application. Instead, an application provides the layout that each attachment must be in at the start and end of a render pass, and the layout it must be in during each subpass it is used in. The implementation then must execute layo= ut transitions between subpasses in order to guarantee that the images are in the layouts required by each subpass, and in the final layout at the end of the render pass.

Automatic layout transitions apply to the entire image subresource attac= hed to the framebuffer. If the attachment view is a 2D or 2D array view of a 3D image, even if the attachment view only refers to a subset of the slices of the selected mip level of the 3D image, automatic layout transitions apply to the entire subresource referenced which is the entire mip level in this case.

Automatic layout transitions away from the layout used in a subpass happen-after the availability operations for all dependencies with that subpass as the srcSubpass.

Automatic layout transitions into the layout used in a subpass happen-be= fore the visibility operations for all dependencies with that subpass as the dstSubpass.

Automatic layout transitions away from initialLayout happen= s-after the availability operations for all dependencies with a srcSubpass= equal to VK_SUBPASS_EXTERNAL, where dstSubpass uses the= attachment that will be transitioned. For attachments created with VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT<= /code>, automatic layout transitions away from initialLayout happen-af= ter the availability operations for all dependencies with a srcSubpass= equal to VK_SUBPASS_EXTERNAL, where dstSubpass uses any= aliased attachment.

Automatic layout transitions into finalLayout happens-befor= e the visibility operations for all dependencies with a dstSubpass e= qual to VK_SUBPASS_EXTERNAL, where srcSubpass uses the at= tachment that will be transitioned. For attachments created with VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT<= /code>, automatic layout transitions into finalLayout happen-before th= e visibility operations for all dependencies with a dstSubpass e= qual to VK_SUBPASS_EXTERNAL, where srcSubpass uses any al= iased attachment.

The image layout of the depth aspect of a depth/stencil attachment refer= ring to an image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT is d= ependent on the last sample locations used to render to the attachment, thus automatic layout transitions use the sample locations state specified in VkRenderPassSampleLocationsBeginIn= foEXT.

Automatic layout transitions of an attachment referring to a depth/stenc= il image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT use = the sample locations the image subresource range referenced by the attachment was last rendered with. If the current render pass does not use the attachment as a depth/stencil attachment in any subpass that happens-before, the automatic layout transition uses the sample locations state specified in the sampleLocationsInfo member of the element of the VkRenderPassSampleLocationsBeginInfoEXT::pAttachmentInit= ialSampleLocations array for which the attachmentIndex member equals the attachme= nt index of the attachment, if one is specified. Otherwise, the automatic layout transition uses the sample locations state specified in the sampleLocationsInfo member of the element of = the VkRenderPassSampleLocationsBeginInfoEXT::pPostSubpassSam= pleLocations array for which the subpassIndex member equals the index of th= e subpass that last used the attachment as a depth/stencil attachment, if one is specified.

If no sample locations state has been specified for an automatic layout transition performed on an attachment referring to a depth/stencil image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EX= T the contents of the depth aspect of the depth/stencil attachment become undefined as if the layout of the attachment was transitioned from the VK_IMAGE_LAYOUT_UNDEFINED layout.

If two subpasses use the same attachment in different layouts, and both layouts are read-only, no subpass dependency needs to be specified between those subpasses. If an implementation treats those layouts separately, it must insert an implicit subpass dependency between those subpasses to separate the uses in each layout. The subpass dependency operates as if defined with the following parameters= :

// Used for input attachments
VkPipelineStageFlags inputAttachmentStages =3D VK_PIPELINE_STAGE_FRAGMENT_S=
HADER_BIT;
VkAccessFlags inputAttachmentAccess =3D VK_ACCESS_INPUT_ATTACHMENT_READ_BIT=
;

// Used for depth/stencil attachments
VkPipelineStageFlags depthStencilAttachmentStages =3D VK_PIPELINE_STAGE_EAR=
LY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
VkAccessFlags depthStencilAttachmentAccess =3D VK_ACCESS_DEPTH_STENCIL_ATTA=
CHMENT_READ_BIT;

VkSubpassDependency implicitDependency =3D {
    .srcSubpass =3D firstSubpass;
    .dstSubpass =3D secondSubpass;
    .srcStageMask =3D inputAttachmentStages | depthStencilAttachmentStages;
    .dstStageMask =3D inputAttachmentStages | depthStencilAttachmentStages;
    .srcAccessMask =3D inputAttachmentAccess | depthStencilAttachmentAccess=
;
    .dstAccessMask =3D inputAttachmentAccess | depthStencilAttachmentAccess=
;
    .dependencyFlags =3D 0;
};

If a subpass uses the same attachment as both an input attachment and ei= ther a color attachment or a depth/stencil attachment, writes via the color or depth/stencil attachment are not automatically made visible to reads via th= e input attachment, causing a feedback loop, except in any of the fo= llowing conditions:

  • If the color components or depth/stencil components read by the input attachment are mutually exclusive with the components written by the color or depth/stencil attachments, then there is no feedback loop. This requires the graphics pipelines used by the subpass to disable writes to color components that are read as inputs via the colorWriteMask, and to disable writes to depth/stencil compone= nts that are read as inputs via depthWriteEnable or stencilTestEnable.

  • If the attachment is used as an input attachment and depth/stencil attachment only, and the depth/stencil attachment is not written to.

  • If a memory dependency is inserted between when the attachment is written and when it is subsequently read by later fragments. Pipeline barriers expressing a subpass self-dependency are the only way to achieve this, and one must be inserted every time a fragment will read values at a particular sample (x, y, layer, sample) coordinate, if those values have been written since the most recent pipeline barrier; or the since start of the subpass if there have been no pipeline barriers since the start of the subpass.

An attachment used as both an input attachment and a color attachment must be in the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or VK_IMAGE_LAYOUT_GENERAL layout. An attachment used as an input attachment and depth/stencil attachment must be in the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, or VK_IMAGE_LAYOUT_GENERAL layout. An attachment must not be used as both a = depth/stencil attachment and a color attachment.

A more extensible version of render pass creation is also defined below.=

To create a render pass, call:

VkResult vkCreateR=
enderPass2KHR(
    VkDevice                                    device,
    const VkRenderPassCreateInfo2KHR*     =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkRenderPass*                               pRenderPass);
  • device is the logical device that creates the render pass.<= /p>

  • pCreateInfo is a pointer to an instance of the VkRenderPassCreateInfo2KHR structure that d= escribes the parameters of the render pass.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pRenderPass points to a VkRenderPass handle in= which the resulting render pass object is returned.

This command is functionally identical to vkCreateRe= nderPass, but includes extensible sub-structures that include sType and pNext parameters, allowing them to be more easily extended.

Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • p= CreateInfo must be a valid pointer= to a valid VkRenderPassCreateInfo2KHR structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllo= cationCallbacks structure

  • p= RenderPass must be a valid pointer= to a VkRenderPass handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkRenderPassCreateInfo2KHR structure is defined as:

typedef struct VkRenderPassCrea=
teInfo2KHR {
    VkStructureType                       sType;
    const void*                           pNext;
    VkRenderPassCreateFlags               flags;
    uint32_t                              attachmentCount;
    const VkAttachmentDescription2KHR*    =
pAttachments;
    uint32_t                              subpassCount;
    const VkSubpassDescription2KHR*       =
pSubpasses;
    uint32_t                              dependencyCount;
    const VkSubpassDependency2KHR*        =
pDependencies;
    uint32_t                              correlatedViewMaskCount;
    const uint32_t*                       =
pCorrelatedViewMasks;
} VkRenderPassCreateInfo2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • attachmentCount is the number of attachments used by this r= ender pass.

  • pAttachments points to an array of attachmentCount VkAttachmentDescription2KHR structures des= cribing the attachments used by the render pass.

  • subpassCount is the number of subpasses to create.

  • pSubpasses points to an array of subpassCount VkSubpassDescription2KHR structures describin= g each subpass.

  • dependencyCount is the number of dependencies between pairs= of subpasses.

  • pDependencies points to an array of dependencyCount VkSubpassDependency2KHR structures describing = dependencies between pairs of subpasses.

  • correlatedViewMaskCount is the number of correlation masks.=

  • pCorrelatedViewMasks is an array of view masks indicating s= ets of views that may be more efficient to rende= r concurrently.

Parameters defined by this structure with the same name as those in VkRenderPassCreateInfo have the identical effec= t to those parameters; the child structures are variants of those used in VkRenderPassCreateInfo which include sTyp= e and pNext parameters, allowing them to be extended.

If the VkSubpassDescription2KHR::vie= wMask member of any element of pSubpasses is not zero, multiview functionality is= considered to be enabled for this render pass.

correlatedViewMaskCount and pCorrelatedViewMasks have the same effect as VkRenderPassMultiviewCreateInfo<= /a>::correlationMaskCount and VkRenderPassMultiviewCreateInfo::<= code>pCorrelationMasks, respectively.

Valid Usage
  • If any two subpasses operate on attachments with overlapping ranges of the same VkDeviceMemory object, and at least one subpass write= s to that area of VkDeviceMemory, a subpass dependency must be included (either directly or via some intermediate subpasses) between them

  • If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments or pDepthStencilAttachment, o= r the attachment indexed by any element of pPreserveAttachments in a= ny given element of pSubpasses is bound to a range of a VkDeviceMemory object that overlaps with any other attachment = in any subpass (including the same subpass), the VkAttachmentDescription2KHR structures describing them must include VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT in flags=

  • If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments or pDepthStencilAttachment, o= r any element of pPreserveAttachments in any given element of pSubpasses is not VK_ATTACHMENT_UNUSED, it must be less than attachmentCount

  • The value of any element of the pPreserveAttachments member in= any given element of pSubpasses must not be VK_ATTACHMENT_UNUSED

  • For any member of pAttachments with a loadOp equa= l to VK_ATTACHMENT_LOAD_OP_CLEAR, the first use of that attachment must not specify a layout eq= ual to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL.

  • For any element of pDependencies, if the srcSubpass is not VK_SUBPASS_EXTERNAL, all stage flags included in the srcStageMask member of that dependency must be a pipeline stage supported by the pipeline identified by the pipelineBindPoint member of the source subpa= ss.

  • For any element of pDependencies, if the dstSubpass is not VK_SUBPASS_EXTERNAL, all stage flags included in the dstStageMask member of that dependency must be a pipeline stage supported by the pipeline identified by the pipelineBindPoint member of the source subpa= ss.

  • The set of bits included in any element of pCorrelatedViewMasks must not overlap with the set of bits inc= luded in any other element of pCorrelatedViewMasks

  • If the VkSubpassDescription2KHR::viewMa= sk member of all elements of pSubpasses is 0, correlatedView= MaskCount must be 0

  • The VkSubpassDescription2KHR::viewMask<= /code> member of all elements of pSubpasses must = either all be 0, or all not be 0

  • If the VkSubpassDescription2KHR::viewMa= sk member of all elements of pSubpasses is 0, the dependency= Flags member of any element of pDependencies must not include VK_DEPENDENCY_VIEW_LOCAL_BIT

  • For any element of pDependencies where its srcSubpass member equals its dstSubpass member, if the viewMask mem= ber of the corresponding element of pSubpasses includes more than one bit= , its dependencyFlags member must include VK_DEPENDENCY_VIEW_LOCAL_BIT

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_REN= DER_PASS_CREATE_INFO_2_KHR

  • pNext must be NULL

  • f= lags must be 0

  • If= attachmentCount is not 0, pAttachments must be a valid pointer to an array o= f attachmentCount valid VkAttachmentDescription2KHR structures

  • pSubpasses must be a valid point= er to an array of subpassCount valid VkSubpassDescriptio= n2KHR structures

  • I= f dependencyCount is not 0, pDependencies must be a valid pointer to an array= of dependencyCount valid VkSubpassDependency2KHR= structures

  • If correlatedViewMaskCount is not 0, = pCorrelatedViewMasks must be a val= id pointer to an array of correlatedViewMaskCount uint32= _t values

  • = subpassCount must be greater= than 0

The VkAttachmentDescription2KHR structure is defined as:

typedef struct VkAttachmentDesc=
ription2KHR {
    VkStructureType                 sType;
    const void*                     pNext;
    VkAttachmentDescriptionFlags    flags;
    VkFormat                        format;
    VkSampleCountFlagBits           samples;
    VkAttachmentLoadOp              loadOp;
    VkAttachmentStoreOp             storeOp;
    VkAttachmentLoadOp              stencilLoadOp;
    VkAttachmentStoreOp             stencilStoreOp;
    VkImageLayout                   initialLayout;
    VkImageLayout                   finalLayout;
} VkAttachmentDescription2KHR;

Parameters defined by this structure with the same name as those in VkAttachmentDescription have the identical eff= ect to those parameters.

Valid Usage
  • finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED

Valid Usage (Implicit)

The VkSubpassDescription2KHR structure is defined as:

typedef struct VkSubpassDescrip=
tion2KHR {
    VkStructureType                     sType;
    const void*                         pNext;
    VkSubpassDescriptionFlags           flags;
    VkPipelineBindPoint                 pipelineBindPoint;
    uint32_t                            viewMask;
    uint32_t                            inputAttachmentCount;
    const VkAttachmentReference2KHR*    pI=
nputAttachments;
    uint32_t                            colorAttachmentCount;
    const VkAttachmentReference2KHR*    pC=
olorAttachments;
    const VkAttachmentReference2KHR*    pR=
esolveAttachments;
    const VkAttachmentReference2KHR*    pD=
epthStencilAttachment;
    uint32_t                            preserveAttachmentCount;
    const uint32_t*                     pP=
reserveAttachments;
} VkSubpassDescription2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkSubpa= ssDescriptionFlagBits specifying usage of the subpass.

  • pipelineBindPoint is a VkPipelineBindP= oint value specifying the pipeline type supported for this subpass.

  • viewMask is a bitfield of view indices describing which vie= ws rendering is broadcast to in this subpass, when multiview is enabled.

  • inputAttachmentCount is the number of input attachments.

  • pInputAttachments is an array of VkA= ttachmentReference structures defining the input attachments for this subpass and their layouts.

  • colorAttachmentCount is the number of color attachments.

  • pColorAttachments is an array of VkA= ttachmentReference structures defining the color attachments for this subpass and their layouts.

  • pResolveAttachments is an optional array of colorAttachmentCount VkAttachmentRefere= nce structures defining the resolve attachments for this subpass and their layouts.

  • pDepthStencilAttachment is a pointer to a VkAttachmentReference specifying the depth/stenc= il attachment for this subpass and its layout.

  • preserveAttachmentCount is the number of preserved attachme= nts.

  • pPreserveAttachments is an array of preserveAttachmen= tCount render pass attachment indices identifying attachments that are not used by this subpass, but whose contents must = be preserved throughout the subpass.

Parameters defined by this structure with the same name as those in VkSubpassDescription have the identical effect to= those parameters.

viewMask has the same effect for the described subpass as VkRenderPassMultiviewCreateInfo::pViewMasks has on each corresponding subpass.

Valid Usage
  • pipelineBindPoint must be VK_PIPELINE_BIND_POINT_GRAPHICS

  • colorAttachmentCount must be= less than or equal to VkPhysicalDeviceLimits::maxColorAttachments

  • If the first use of an attachment in this render pass is as an input attachment, and the attachment is not also used as a color or depth/stencil attachment in the same subpass, then loadOp must not be VK_ATTACHMENT_LOAD_OP_CLEAR

  • If pResolveAttachments is not NULL, for each reso= lve attachment that does not have the value VK_ATTACHMENT_UNUSED, the corresponding color attachment must not h= ave the value VK_ATTACHMENT_UNUSED

  • If pResolveAttachments is not NULL, the sample co= unt of each element of pColorAttachments must be anything other than VK_SAMPLE_COUNT_1_BIT

  • Any given element of pResolveAttachments must have a sample count of VK_SAMPLE_COUNT_1_BIT

  • Any given element of pResolveAttachments must have the same VkFormat as its corresponding color attachment

  • All attachments in pColorAttachments that are not VK_ATTACHMENT_UNUSED must ha= ve the same sample count

  • All attachments in pColorAttachments that are not VK_ATTACHMENT_UNUSED must ha= ve a sample count that is smaller than or equal to the sample count of pDepthStencilAttachment i= f it is not VK_ATTACHMENT_UNUSED

  • If any input attachments are VK_ATTACHMENT_UNUSED, then any pipelines bound during the subpass must n= ot access those input attachments from the fragment shader

  • The attachment member of any element of pPreserveAttachm= ents must not be VK_ATTACHMENT_UNUSED

  • Any given element of pPreserveAttachments must not also be an element of any other member of the subpass description

  • If any attachment is used as both an input attachment and a color or depth/stencil attachment, then each use must use the same layout

  • If flags includes VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX, it must also include VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX.

  • The aspectMask member of any element of pInputAttachment= s must be a valid combination of VkImageAspectFlagBits

  • The aspectMask member of any element of pInputAttachment= s must not be 0

Valid Usage (Implicit)

The VkAttachmentReference2KHR structure is defined as:

typedef struct VkAttachmentRefe=
rence2KHR {
    VkStructureType       sType;
    const void*           pNext;
    uint32_t              attachment;
    VkImageLayout         layout;
    VkImageAspectFlags    aspectMask;
} VkAttachmentReference2KHR;

Parameters defined by this structure with the same name as those in VkAttachmentReference have the identical effect = to those parameters.

aspectMask has the same effect for the described attachment= as VkInputAttachmentAspectReference::aspectMask has on each corresponding attachment. It is ignored when this structure is used to describe anything other than a= n input attachment reference.

Valid Usage
  • layout must not be VK_= IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_ATTA= CHMENT_REFERENCE_2_KHR

  • lay= out must be a valid VkImageLayout value

The VkSubpassDependency2KHR structure is defined as:

typedef struct VkSubpassDepende=
ncy2KHR {
    VkStructureType         sType;
    const void*             pNext;
    uint32_t                srcSubpass;
    uint32_t                dstSubpass;
    VkPipelineStageFlags    srcStageMask;
    VkPipelineStageFlags    dstStageMask;
    VkAccessFlags           srcAccessMask;
    VkAccessFlags           dstAccessMask;
    VkDependencyFlags       dependencyFlags;
    int32_t                 viewOffset;
} VkSubpassDependency2KHR;

Parameters defined by this structure with the same name as those in VkSubpassDependency have the identical effect to t= hose parameters.

viewOffset has the same effect for the described subpass de= pendency as VkRenderPassMultiviewCreateInfo::pViewOffsets has on each corresponding subpass dependency.

Valid Usage
  • If srcSubpass is not VK_SUBPASS_EXTERNAL, s= rcStageMask must not include VK_PIPELINE_STAGE_= HOST_BIT

  • If dstSubpass is not VK_SUBPASS_EXTERNAL, d= stStageMask must not include VK_PIPELINE_STAGE_= HOST_BIT

  • If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

  • If the tessellation shaders feature is not enabled, srcStageMask = must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • If the tessellation shaders feature is not enabled, dstStageMask = must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

  • srcSubpass must be less than= or equal to dstSubpass, unless one of them is VK_SUBPASS_EXTERNAL, to avoid cyclic dependenci= es and ensure a valid execution order

  • srcSubpass and dstSubpass must not both be equal to VK_SUBPASS_EXTERNAL

  • If srcSubpass is equal to dstSubpass, srcSt= ageMask and dstStageMask must only conta= in one of VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, or VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT

  • If srcSubpass is equal to dstSubpass and not all = of the stages in srcStageMask and dstStageMask are framebuffer-space stages, the logically latest pipeline stage in srcStageMask must b= e logically earlier than or equal to the logically earliest pipeline stage in dstStageMask

  • Any access flag included in srcAccessMask must be supported by one of the pipeline stages in srcStageMask, as specified in th= e table of supported access types

  • Any access flag included in dstAccessMask must be supported by one of the pipeline stages in dstStageMask, as specified in th= e table of supported access types

  • If dependencyFlags includes VK_DEPENDENCY_VIEW_LOCAL_BIT= , srcSubpass must not be equal= to VK_SUBPASS_EXTERNAL

  • If dependencyFlags includes VK_DEPENDENCY_VIEW_LOCAL_BIT= , dstSubpass must not be equal= to VK_SUBPASS_EXTERNAL

  • If dependencyFlags does not include VK_DEPENDENCY_VIEW_LOCAL_BIT, viewOffset must be 0

  • If viewOffset is not 0, srcSubpass <= strong class=3D"purple">must not be equal to dstSubpass.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_SUBPAS= S_DEPENDENCY_2_KHR

  • srcStageMask must be a valid comb= ination of VkPipelineStageFlagBits values

  • = srcStageMask must not be 0

  • dstStageMask must be a valid comb= ination of VkPipelineStageFlagBits values

  • = dstStageMask must not be 0

  • srcAccessMask must be a valid co= mbination of VkAccessFlagBits values

  • dstAccessMask must be a valid co= mbination of VkAccessFlagBits values

  • dependencyFlags must be a vali= d combination of VkDependencyFlagBits values

To destroy a render pass, call:

void vkDestroyRenderPass(
    VkDevice                                    device,
    VkRenderPass                                renderPass,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the render pass.=

  • renderPass is the handle of the render pass to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to renderPass must have completed execution

  • If VkAllocationCallbacks were provided when renderPass was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when renderPas= s was created, pAllocator must= be NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • If re= nderPass is not VK_NULL_HANDLE, renderPass= must be a valid VkRenderPas= s handle

  • If pA= llocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocat= ionCallbacks structure

  • If rende= rPass is a valid handle, it must h= ave been created, allocated, or retrieved from device

Host Synchronization
  • Host access to renderPass must be externally synchronized

7.2. Render Pass Compatibility

Framebuffers and graphics pipelines are created based on a specific rend= er pass object. They must only be used with that render p= ass object, or one compatible with it.

Two attachment references are compatible if they have matching format an= d sample count, or are both VK_ATTACHMENT_UNUSED or the pointer = that would contain the reference is NULL.

Two arrays of attachment references are compatible if all corresponding pairs of attachments are compatible. If the arrays are of different lengths, attachment references not present i= n the smaller array are treated as VK_ATTACHMENT_UNUSED.

Two render passes are compatible if their corresponding color, input, resolve, and depth/stencil attachment references are compatible and if they are otherwise identical except for:

  • Initial and final image layout in attachment descriptions

  • Load and store operations in attachment descriptions

  • Image layout in attachment references

A framebuffer is compatible with a render pass if it was created using t= he same render pass or a compatible render pass.

7.3. Framebuffers

Render passes operate in conjunction with framebuffers. Framebuffers represent a collection of specific memory attachments that a render pass instance uses.

Framebuffers are represented by VkFramebuffer handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkFramebuffer)

To create a framebuffer, call:

VkResult vkCreateF=
ramebuffer(
    VkDevice                                    device,
    const VkFramebufferCreateInfo*        =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkFramebuffer*                              pFramebuffer);
  • device is the logical device that creates the framebuffer.<= /p>

  • pCreateInfo points to a VkFramebuf= ferCreateInfo structure which describes additional information about framebuffer creation.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pFramebuffer points to a VkFramebuffer h= andle in which the resulting framebuffer object is returned.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pCre= ateInfo must be a valid pointer to= a valid VkFramebufferCreateInfo structure

  • If pA= llocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocat= ionCallbacks structure

  • pFr= amebuffer must be a valid pointer = to a VkFramebuffer handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkFramebufferCreateInfo structure is defined as:

typedef struct VkFramebufferCre=
ateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkFramebufferCreateFlags    flags;
    VkRenderPass                renderPass;
    uint32_t                    attachmentCount;
    const VkImageView*          pAttachmen=
ts;
    uint32_t                    width;
    uint32_t                    height;
    uint32_t                    layers;
} VkFramebufferCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • renderPass is a render pass that defines what render passes= the framebuffer will be compatible with. See Render Pass Compatibility for details.

  • attachmentCount is the number of attachments.

  • pAttachments is an array of VkImageView ha= ndles, each of which will be used as the corresponding attachment in a render pass instance.

  • width, height and layers define t= he dimensions of the framebuffer. If the render pass uses multiview, then layers must be one and each attachment requires a number of layers that is greater than the maximum bit index set in the view mask in the subpasses in which it is used.

Applications must ensure that all acce= sses to memory that backs image subresources used as attachments in a given renderpass instance either happen-before the load operations for those attachments, or happen-after the store operations for those attachments.

For depth/stencil attachments, each aspect can<= /strong> be used separately as attachments and non-attachments as long as the non-attachment accesses are also via an image subresource in either the VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL lay= out or the VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL= layout, and the attachment resource uses whichever of those two layouts the image accesses do not. Use of non-attachment aspects in this case is only well defined if the attachment is used in the subpass where the non-attachment access is being made, or the layout of the image subresource is constant throughout the entire render pass instance, including the initialLayout and finalLayout.

Note

These restrictions mean that the render pass has full knowledge of all uses of all of the attachments, so that the implementation is able to make correct decisions about when and how to perform layout transitions, when to overlap execution of subpasses, etc.

It is legal for a subpass to use no color or depth/stencil attachments, = and rather use shader side effects such as image stores and atomics to produce an output. In this case, the subpass continues to use the width, he= ight, and layers of the framebuffer to define the dimensions of the rendering area, and the rasterizationSamples from each pipelin= e=E2=80=99s VkPipelineMultisampleStateCreateInfo<= /a> to define the number of samples used in rasterization; however, if VkPhysicalDeviceFeatures::variableMulti= sampleRate is VK_FALSE, then all pipelines to be bound with a given zero-att= achment subpass must have the same value for VkPipelineMultisampleStateCreateInfo<= /a>::rasterizationSamples.

Valid Usage
  • attachmentCount must be equa= l to the attachment count specified in renderPass

  • Each element of pAttachments that is used as a color attachmen= t or resolve attachment by renderPass must= have been created with a usage value including VK_IMAGE_USAGE_COLOR_ATTACHMENT_BI= T

  • Each element of pAttachments that is used as a depth/stencil attachment by renderPass must have been created with a usage value including VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT

  • Each element of pAttachments that is used as an input attachme= nt by renderPass must have been= created with a usage value including VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT

  • Each element of pAttachments must have been created with an VkFormat value that matches the VkFormat specif= ied by the corresponding VkAttachmentDescription in renderPass

  • Each element of pAttachments must have been created with a samples value that matches the samples value spec= ified by the corresponding VkAttachmentDescription in renderPass<= /code>

  • Each element of pAttachments must have dimensions at least as large as the corresponding framebuffer dimension

  • Each element of pAttachments must only specify a single mip level

  • Each element of pAttachments must have been created with the identity swizzle

  • width must be greater than <= code>0.

  • width must be less than or e= qual to VkPhysicalDeviceLimits::maxFramebufferWidth

  • height must be greater than = 0.

  • height must be less than or = equal to VkPhysicalDeviceLimits::maxFramebufferHeight

  • layers must be greater than = 0.

  • layers must be less than or = equal to VkPhysicalDeviceLimits::maxFramebufferLayers

  • Each element of pAttachments that is a 2D or 2D array image vi= ew taken from a 3D image must not be a depth= /stencil format

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_FRAMEB= UFFER_CREATE_INFO

  • pNext must be NULL

  • flag= s must be 0

  • r= enderPass must be a valid Vk= RenderPass handle

  • If attachmentCount is not 0, pAttachments= must be a valid pointer to an array of <= code>attachmentCount valid VkImageView handles

  • Both of r= enderPass, and the elements of pAttachments that are va= lid handles must have been created, alloc= ated, or retrieved from the same VkDevice

typedef VkFlags VkFramebufferCreateFlags;

VkFramebufferCreateFlags is a bitmask type for setting a ma= sk, but is currently reserved for future use.

To destroy a framebuffer, call:

void vkDestroyFramebuffer(
    VkDevice                                    device,
    VkFramebuffer                               framebuffer,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the framebuffer.=

  • framebuffer is the handle of the framebuffer to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to framebuffer must have completed execution

  • If VkAllocationCallbacks were provided when framebuffer<= /code> was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when framebuff= er was created, pAllocator must= be NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • If = framebuffer is not VK_NULL_HANDLE, framebu= ffer must be a valid VkFrame= buffer handle

  • If p= Allocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloca= tionCallbacks structure

  • If fra= mebuffer is a valid handle, it must have been created, allocated, or retrieved from device

Host Synchronization
  • Host access to framebuffer must be externally synchronized

7.4. Render Pass Commands

An application records the commands for a render pass instance one subpa= ss at a time, by beginning a render pass instance, iterating over the subpasse= s to record commands for that subpass, and then ending the render pass instance.

To begin a render pass instance, call:

void vkCmdBeginRenderPass(
    VkCommandBuffer                             commandBuffer,
    const VkRenderPassBeginInfo*          =
      pRenderPassBegin,
    VkSubpassContents                           contents);
  • commandBuffer is the command buffer in which to record the command.

  • pRenderPassBegin is a pointer to a V= kRenderPassBeginInfo structure (defined below) which specifies the render pass to begin an instance of, and the framebuffer the instance uses.

  • contents is a VkSubpassContents valu= e specifying how the commands in the first subpass will be provided.

After beginning a render pass instance, the command buffer is ready to record the commands for the first subpass of that render pass.

Valid Usage
  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPT= IMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin<= /code> must have been created with VK_IMAG= E_USAGE_COLOR_ATTACHMENT_BIT set

  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, or VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = set

  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPT= IMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin<= /code> must have been created with VK_IMAG= E_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set

  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL= then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin<= /code> must have been created with VK_IMAG= E_USAGE_TRANSFER_SRC_BIT set

  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL= then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin<= /code> must have been created with VK_IMAG= E_USAGE_TRANSFER_DST_BIT set

  • If any of the initialLayout members of the VkAttachmentDescription structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is not VK_IMAGE_LAYOUT_UNDEFINED= , then each such initialLayout must be e= qual to the current layout of the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin

  • The srcStageMask and dstStageMask members of any = element of the pDependencies member of VkRenderPa= ssCreateInfo used to create renderPass must be su= pported by the capabilities of the queue family identified by the queueFamilyIndex member of the VkCommandPoolCreateInfo used to create the com= mand pool which commandBuffer was allocated from.

Valid Usage (Implicit)
  • c= ommandBuffer must be a valid VkCommandBuffer handle

  • pRenderPassBegin must be a valid= pointer to a valid VkRenderPassBeginInfo structure

  • conten= ts must be a valid VkSubpassContents value

  • c= ommandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • This command must only be called outside of a render pass ins= tance

  • commandBuffer= must be a primary VkCommand= Buffer

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary

Out= side

Gra= phics

Gra= phics

Alternatively to begin a render pass, call:

void vkCmdBeginRenderPass2KHR(
    VkCommandBuffer                             commandBuffer,
    const VkRenderPassBeginInfo*          =
      pRenderPassBegin,
    const VkSubpassBeginInfoKHR*          =
      pSubpassBeginInfo);
  • commandBuffer is the command buffer in which to record the command.

  • pRenderPassBegin is a pointer to a V= kRenderPassBeginInfo structure (defined below) which indicates the render pass to begin an instance of, and the framebuffer the instance uses.

  • pSubpassBeginInfo is a pointer to a = VkSubpassBeginInfoKHR structure which contains information about the subpass which is about to begin rendering.

After beginning a render pass instance, the command buffer is ready to record the commands for the first subpass of that render pass.

Valid Usage
  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPT= IMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin<= /code> must have been created with VK_IMAG= E_USAGE_COLOR_ATTACHMENT_BIT set

  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, or VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = set

  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPT= IMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin<= /code> must have been created with VK_IMAG= E_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set

  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL= then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin<= /code> must have been created with VK_IMAG= E_USAGE_TRANSFER_SRC_BIT set

  • If any of the initialLayout or finalLayout member= of the VkAttachmentDescription structures or the layout = member of the VkAttachmentReference structures specified when creating t= he render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL= then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin<= /code> must have been created with VK_IMAG= E_USAGE_TRANSFER_DST_BIT set

  • If any of the initialLayout members of the VkAttachmentDescription structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is not VK_IMAGE_LAYOUT_UNDEFINED= , then each such initialLayout must be e= qual to the current layout of the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin

  • The srcStageMask and dstStageMask members of any = element of the pDependencies member of VkRenderPa= ssCreateInfo used to create renderPass must be su= pported by the capabilities of the queue family identified by the queueFamilyIndex member of the VkCommandPoolCreateInfo used to create the com= mand pool which commandBuffer was allocated from.

Valid Usage (Implicit)
  • commandBuffer must be a valid <= code>VkCommandBuffer handle

  • = pRenderPassBegin must be a v= alid pointer to a valid VkRenderPassBeginInfo structure

  • = pSubpassBeginInfo must be a= valid pointer to a valid VkSubpassBeginInfoKHR structure

  • commandBuffer must be in the recording state

  • The <= code>VkCommandPool that commandBuffer was allocated fro= m must support graphics operations

  • This command must only be called outside of a render pass= instance

  • commandBu= ffer must be a primary VkCom= mandBuffer

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary

Out= side

Gra= phics

Gra= phics

The VkRenderPassBeginInfo structure is defined as:

typedef struct VkRenderPassBegi=
nInfo {
    VkStructureType        sType;
    const void*            pNext;
    VkRenderPass           renderPass;
    VkFramebuffer          framebuffer;
    VkRect2D               renderArea;
    uint32_t               clearValueCount;
    const VkClearValue*    pClearValues;
} VkRenderPassBeginInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • renderPass is the render pass to begin an instance of.

  • framebuffer is the framebuffer containing the attachments t= hat are used with the render pass.

  • renderArea is the render area that is affected by the rende= r pass instance, and is described in more detail below.

  • clearValueCount is the number of elements in pClearVa= lues.

  • pClearValues is an array of VkClearValue = structures that contains clear values for each attachment, if the attachment uses a loadOp value of VK_ATTACHMENT_LOAD_OP_CLEAR or if= the attachment has a depth/stencil format and uses a stencilLoadOp value of VK_ATTACHMENT_LOAD_OP_CLEAR. The array is indexed by attachment number. Only elements corresponding to cleared attachments are used. Other elements of pClearValues are ignored.

renderArea is the render area that is affected by the rende= r pass instance. The effects of attachment load, store and multisample resolve operations ar= e restricted to the pixels whose x and y coordinates fall within the render area on all attachments. The render area extends to all layers of framebuffer. The application must ensure (using scisso= r if necessary) that all rendering is contained within the render area, otherwise the pixels outside of the render area become undefined and shader side effects may occur for fragments outside the render area. The render area must be contained within = the framebuffer dimensions.

When multiview is enabled, the resolve operation at the end of a subpass applies to all views in the view mask.

Note

There may be a performance cost for us= ing a render area smaller than the framebuffer, unless it matches the render area granularity for the render pass.

Valid Usage
  • clearValueCount must be grea= ter than the largest attachment index in renderPass that specifies a loadOp (or stencilLoadOp, if the attachment has a depth/stencil format) o= f VK_ATTACHMENT_LOAD_OP_CLEAR

  • If clearValueCount is not 0, pClearValues must be a valid pointer to an array of clearValueCount valid VkClearValu= e unions

  • renderPass must be compatible with the renderPass member of the VkFramebufferCreateInfo structure specified when creating framebuffer.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_RENDER_P= ASS_BEGIN_INFO

  • Each pNext member of any structure (including this one) in the pNext chain must be either NULL = or a pointer to a valid instance of VkDev= iceGroupRenderPassBeginInfo or VkRenderPassSampleLocationsBeginInfoEXT

  • Each sType<= /code> member in the pNext chain must= be unique

  • ren= derPass must be a valid VkRe= nderPass handle

  • fr= amebuffer must be a valid Vk= Framebuffer handle

  • Both of fra= mebuffer, and renderPass must<= /strong> have been created, allocated, or retrieved from the same VkD= evice

The image layout of the depth aspect of a depth/stencil attachment refer= ring to an image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT is d= ependent on the last sample locations used to render to the image subresource, thus preserving the contents of such depth/stencil attachments across subpass boundaries requires the application to specify these sample locations whenever a layout transition of the attachment may= occur. This information can be provided by chain= ing an instance of the VkRenderPassSampleLocationsBeginInfoEXT structure to the pNext chain of VkRenderPassBeginInfo.

The VkRenderPassSampleLocationsBeginInfoEXT structure is de= fined as:

typedef struct VkRenderPassSamp=
leLocationsBeginInfoEXT {
    VkStructureType                          sType;
    const void*                              pNext;
    uint32_t                                 attachmentInitialSampleLocatio=
nsCount;
    const VkAttachmentSampleLocationsEXT* =
   pAttachmentInitialSampleLocations;
    uint32_t                                 postSubpassSampleLocationsCoun=
t;
    const VkSubpassSampleLocationsEXT*    =
   pPostSubpassSampleLocations;
} VkRenderPassSampleLocationsBeginInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • attachmentInitialSampleLocationsCount is the number of elem= ents in the pAttachmentInitialSampleLocations array.

  • pAttachmentInitialSampleLocations is an array of attachmentInitialSampleLocationsCount VkAttachmentSampleLocationsEXT structur= es specifying the attachment indices and their corresponding sample location state. Each element of pAttachmentInitialSampleLocations can specify the sample location state to use in the automatic layout transition performed to transition a depth/stencil attachment from the initial layout of the attachment to the image layout specified for the attachment in the first subpass using it.

  • postSubpassSampleLocationsCount is the number of elements i= n the pPostSubpassSampleLocations array.

  • pPostSubpassSampleLocations is an array of postSubpassSampleLocationsCount V= kSubpassSampleLocationsEXT structures specifying the subpass indices and their corresponding sample location state. Each element of pPostSubpassSampleLocations can specify the sample location state to use in the automatic layout transition performed to transition the depth/stencil attachment used by the specified subpass to the image layout specified in a dependent subpass or to the final layout of the attachment in case the specified subpass is the last subpass using that attachment. In addition, if VkPhysicalDeviceSampleLocatio= nsPropertiesEXT::variableSampleLocations is VK_FALSE, each element of pPostSubpassSampleLocations= must specify the sample location state th= at matches the sample locations used by all pipelines that will be bound to a command buffer during the specified subpass. If variableSampleLocations is VK_TRUE, the sample= locations used for rasterization do not depend on pPostSubpassSampleLocations.

Valid Usage (Implicit)
  • = sType must be VK_STRUC= TURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT

  • If attachmentInitialSampleLocationsCo= unt is not 0, pAttachmentInitialSampleLocations must be a valid pointer to an array= of attachmentInitialSampleLocationsCount valid VkAttach= mentSampleLocationsEXT structures

  • If postSubpassSampleLocationsCount i= s not 0, pPostSubpassSampleLocations must be a valid pointer to an array of postSubp= assSampleLocationsCount valid VkSubpassSampleLocationsEXT structures

The VkAttachmentSampleLocationsEXT structure is defined as:=

typedef struct VkAttachmentSamp=
leLocationsEXT {
    uint32_t                    attachmentIndex;
    VkSampleLocationsInfoEXT    sampleLocationsInfo;
} VkAttachmentSampleLocationsEXT;
  • attachmentIndex is the index of the attachment for which th= e sample locations state is provided.

  • sampleLocationsInfo is the sample locations state to use fo= r the layout transition of the given attachment from the initial layout of the attachment to the image layout specified for the attachment in the first subpass using it.

If the image referenced by the framebuffer attachment at index attachmentIndex was not created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT then= the values specified in sampleLocationsInfo are ignored.

Valid Usage
Valid Usage (Implicit)
  • sampleLocationsInfo must be a valid VkSampleLocationsInfoEXT structure

The VkSubpassSampleLocationsEXT structure is defined as:

typedef struct VkSubpassSampleL=
ocationsEXT {
    uint32_t                    subpassIndex;
    VkSampleLocationsInfoEXT    sampleLocationsInfo;
} VkSubpassSampleLocationsEXT;
  • subpassIndex is the index of the subpass for which the samp= le locations state is provided.

  • sampleLocationsInfo is the sample locations state to use fo= r the layout transition of the depth/stencil attachment away from the image layout the attachment is used with in the subpass specified in subpassIndex.

If the image referenced by the depth/stencil attachment used in the subp= ass identified by subpassIndex was not created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT or i= f the subpass does not use a depth/stencil attachment, and VkPhysicalDeviceSampleLocatio= nsPropertiesEXT::variableSampleLocations is VK_TRUE then the values specified in sampleLocationsI= nfo are ignored.

Valid Usage
Valid Usage (Implicit)
  • sampleLocationsInfo must be a valid VkSampleLocationsInfoEXT structure

The VkSubpassBeginInfoKHR structure is defined as:

typedef struct VkSubpassBeginIn=
foKHR {
    VkStructureType      sType;
    const void*          pNext;
    VkSubpassContents    contents;
} VkSubpassBeginInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • contents is a VkSubpassContents valu= e specifying how the commands in the next subpass will be provided.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_SUBPASS_= BEGIN_INFO_KHR

  • pNext= must be NULL

  • conte= nts must be a valid VkSubpassContents value

Possible values of vkCmdBeginRenderPass::contents, specifying how the commands in the first subpass will be provided, are:

typedef enum VkSubpassContents =
{
    VK_SUBPASS_CONTENTS_INLINE =3D 0,
    VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS =3D 1,
} VkSubpassContents;
  • VK_SUBPASS_CONTENTS_INLINE specifies that the contents of t= he subpass will be recorded inline in the primary command buffer, and secondary command buffers must not be exe= cuted within the subpass.

  • VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS specifies tha= t the contents are recorded in secondary command buffers that will be called from the primary command buffer, and vkCmdExecuteComm= ands is the only valid command on the command buffer until vkCmdNextS= ubpass or vkCmdEndRenderPass.

If the pNext chain of VkRenderPassBe= ginInfo includes a VkDeviceGroupRenderPassBeginInfo structure, then that structur= e includes a device mask and set of render areas for the render pass instance= .

The VkDeviceGroupRenderPassBeginInfo structure is defined a= s:

typedef struct VkDeviceGroupRen=
derPassBeginInfo {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           deviceMask;
    uint32_t           deviceRenderAreaCount;
    const VkRect2D*    pDeviceRenderAreas;
} VkDeviceGroupRenderPassBeginInfo;

or the equivalent

typedef VkDeviceGroupRenderPassBeginInfo VkDeviceGroupRenderPa=
ssBeginInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • deviceMask is the device mask for the render pass instance.=

  • deviceRenderAreaCount is the number of elements in the pDeviceRenderAreas array.

  • pDeviceRenderAreas is an array of structures of type VkRect2D defining the render area for each physical device.

The deviceMask serves several purposes. It is an upper bound on the set of physical devices that can be used during the render pass instance, and the initial device mask when the render pass instance begins. Render pass attachment load, store, and resolve operations only apply to physical devices included in the device mask. Subpass dependencies only apply to the physical devices in the device mask.=

If deviceRenderAreaCount is not zero, then the elements of pDeviceRenderAreas override the value of VkRenderPassBeginInfo::renderArea, = and provide a render area specific to each physical device. These render areas serve the same purpose as VkRenderPassBeginInfo::renderArea, = including controlling the region of attachments that are cleared by VK_ATTACHMENT_LOAD_OP_CLEAR= and that are resolved into resolve attachments.

If this structure is not present, the render pass instance=E2=80=99s dev= ice mask is the value of VkDeviceGroupCommandBuffe= rBeginInfo::deviceMask. If this structure is not present or if deviceRenderAreaCount i= s zero, VkRenderPassBeginInfo::renderArea i= s used for all physical devices.

Valid Usage
  • deviceMask must be a valid d= evice mask value

  • deviceMask must not be zero<= /p>

  • deviceMask must be a subset = of the command buffer=E2=80=99s initial device mask

  • deviceRenderAreaCount must e= ither be zero or equal to the number of physical devices in the logical device.

Valid Usage (Implicit)
  • s= Type must be VK_STRUCTURE_TY= PE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO

  • If deviceRenderAreaCount is not 0, pDeviceRenderAreas must be a val= id pointer to an array of deviceRenderAreaCount VkRect2D= structures

To query the render area granularity, call:

void vkGetRenderAreaGranularity(
    VkDevice                                    device,
    VkRenderPass                                renderPass,
    VkExtent2D*                                 pGranularity);
  • device is the logical device that owns the render pass.

  • renderPass is a handle to a render pass.

  • pGranularity points to a VkExtent2D structu= re in which the granularity is returned.

The conditions leading to an optimal renderArea are:

  • the offset.x member in renderArea is a multipl= e of the width member of the returned VkExtent2D (the h= orizontal granularity).

  • the offset.y member in renderArea is a multipl= e of the height of the returned VkExtent2D (the vertica= l granularity).

  • either the offset.width member in renderArea i= s a multiple of the horizontal granularity or offset.x+offset.width is equal to the width of the framebuffer in the VkRenderPassBeginInfo.

  • either the offset.height member in renderArea = is a multiple of the vertical granularity or offset.y+offset.height is equal to the height of the framebuffer in the VkRenderPassBeginInfo.

Subpass dependencies are not affected by the render area, and apply to t= he entire image subresources attached to the framebuffer as specified in the description of automatic layout transitions. Similarly, pipeline barriers are valid even if their effect extends outside the render area.

Valid Usage (Implicit)
  • de= vice must be a valid VkDevic= e handle

  • renderPass must be a valid VkRenderPass handle

  • pGranularity must be a valid p= ointer to a VkExtent2D structure

  • r= enderPass must have been created, = allocated, or retrieved from device

To transition to the next subpass in the render pass instance after recording the commands for a subpass, call:

void vkCmdNextSubpass(
    VkCommandBuffer                             commandBuffer,
    VkSubpassContents                           contents);
  • commandBuffer is the command buffer in which to record the command.

  • contents specifies how the commands in the next subpass wil= l be provided, in the same fashion as the corresponding parameter of vkCmdBeginRenderPass.

The subpass index for a render pass begins at zero when vkCmdBeginRenderPass is recorded, and increments each time vkCmdNextSubpass is recorded.

Moving to the next subpass automatically performs any multisample resolv= e operations in the subpass being ended. End-of-subpass multisample resolves are treated as color attachment writes for the purposes of synchronization. That is, they are considered to execute in the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage a= nd their writes are synchronized with VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT. Synchronization between rendering within a subpass and any resolve operations at the end of the subpass occurs automatically, without need for explicit dependencies or pipeline barriers. However, if the resolve attachment is also used in a different subpass, an explicit dependency is needed.

After transitioning to the next subpass, the application can record the commands for that subpass.

Valid Usage
  • The current subpass index must be less th= an the number of subpasses in the render pass minus one

Valid Usage (Implicit)
  • comma= ndBuffer must be a valid VkC= ommandBuffer handle

  • contents must be a valid = VkSubpassContents value

  • comma= ndBuffer must be in the recording state

  • The VkC= ommandPool that commandBuffer was allocated from must support graphics operations

  • This command must only be called inside of a render pass instance=

  • commandBuffer must be a primary VkCommandBuff= er

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary

Ins= ide

Gra= phics

Gra= phics

To transition to the next subpass in the render pass instance after recording the commands for a subpass, call:

void vkCmdNextSubpass2KHR(
    VkCommandBuffer                             commandBuffer,
    const VkSubpassBeginInfoKHR*          =
      pSubpassBeginInfo,
    const VkSubpassEndInfoKHR*            =
      pSubpassEndInfo);
  • commandBuffer is the command buffer in which to record the command.

  • pSubpassBeginInfo is a pointer to a = VkSubpassBeginInfoKHR structure which contains information about the subpass which is about to begin rendering.

  • pSubpassEndInfo is a pointer to a VkSu= bpassEndInfoKHR structure which contains information about how the previous subpass will be ended.

vkCmdNextSubpass2KHR is semantically identical to vkCmdNextSubpass, except that it is extensible, and t= hat contents is provided as part of an extensible structure instea= d of as a flat parameter.

Valid Usage
  • The current subpass index must be less th= an the number of subpasses in the render pass minus one

Valid Usage (Implicit)
  • c= ommandBuffer must be a valid VkCommandBuffer handle

  • pSubpassBeginInfo must be a val= id pointer to a valid VkSubpassBeginInfoKHR structure

  • pSubpassEndInfo must be a valid p= ointer to a valid VkSubpassEndInfoKHR structure

  • c= ommandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • This command must only be called inside of a render pass inst= ance

  • commandBuffer= must be a primary VkCommand= Buffer

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary

Ins= ide

Gra= phics

Gra= phics

To record a command to end a render pass instance after recording the commands for the last subpass, call:

void vkCmdEndRenderPass(
    VkCommandBuffer                             commandBuffer);
  • commandBuffer is the command buffer in which to end the cur= rent render pass instance.

Ending a render pass instance performs any multisample resolve operation= s on the final subpass.

Valid Usage
  • The current subpass index must be equal t= o the number of subpasses in the render pass minus one

Valid Usage (Implicit)
  • com= mandBuffer must be a valid V= kCommandBuffer handle

  • com= mandBuffer must be in the recording state

  • The V= kCommandPool that commandBuffer was allocated from must support graphics operations

  • This command must only be called inside of a render pass instan= ce

  • commandBuffer must be a primary VkCommandBu= ffer

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary

Ins= ide

Gra= phics

Gra= phics

To record a command to end a render pass instance after recording the commands for the last subpass, call:

void vkCmdEndRenderPass2KHR(
    VkCommandBuffer                             commandBuffer,
    const VkSubpassEndInfoKHR*            =
      pSubpassEndInfo);
  • commandBuffer is the command buffer in which to end the cur= rent render pass instance.

  • pSubpassEndInfo is a pointer to a VkSu= bpassEndInfoKHR structure which contains information about how the previous subpass will be ended.

vkCmdEndRenderPass2KHR is semantically identical to vkCmdEndRenderPass, except that it is extensible.

Valid Usage
  • The current subpass index must be equal t= o the number of subpasses in the render pass minus one

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • pSubpassEndInfo must be a valid= pointer to a valid VkSubpassEndInfoKHR structure

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from = must support graphics operations

  • This command must only be called inside of a render pass in= stance

  • commandBuff= er must be a primary VkComma= ndBuffer

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary

Ins= ide

Gra= phics

Gra= phics

The VkSubpassEndInfoKHR structure is defined as:

typedef struct VkSubpassEndInfo=
KHR {
    VkStructureType    sType;
    const void*        pNext;
} VkSubpassEndInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

Valid Usage (Implicit)
  • sType <= strong class=3D"purple">must be VK_STRUCTURE_TYPE_SUBPASS_EN= D_INFO_KHR

  • pNext <= strong class=3D"purple">must be NULL

8. Shaders

A shader specifies programmable operations that execute for each vertex, control point, tessellated vertex, primitive, fragment, or workgroup in the corresponding stage(s) of the graphics and compute pipelines.

Graphics pipelines include vertex shader execution as a result of primitive assembly, followed, if enabled, by tessellation control and evaluation shaders operating on patches, geometry shaders, if enabled, operating on primitives, and fragment shaders, if present, operating on fragments generated by Rasterization. In this specification, vertex, tessellation control, tessellation evaluatio= n and geometry shaders are collectively referred to as vertex processing stages and occur in the logical pipeline before rasterization. The fragment shader occurs logically after rasterization.

Only the compute shader stage is included in a compute pipeline. Compute shaders operate on compute invocations in a workgroup.

Shaders can read from input variables,= and read from and write to output variables. Input and output variables can be used to= transfer data between shader stages, or to allow the shader to interact with values that exist in the execution environment. Similarly, the execution environment provides constants that describe capabilities.

Shader variables are associated with execution environment-provided inpu= ts and outputs using built-in decorations in the shader. The available decorations for each stage are documented in the following subsections.

8.1. Shader Modules

Shader modules contain shader code and one or more ent= ry points. Shaders are selected from a shader module by specifying an entry point as part of pipeline creation. The stages of a pipeline can use shaders = that come from different modules. The shader code defining a shader module must be in the SPIR-V format, as described by the Vulkan Environment for SPIR-V appendix.

Shader modules are represented by VkShaderModule handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkShaderModule)

To create a shader module, call:

VkResult vkCreateS=
haderModule(
    VkDevice                                    device,
    const VkShaderModuleCreateInfo*       =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkShaderModule*                             pShaderModule);

If the shader stage fails to compile VK_ERROR_INVALID_SHADER_NV will be generated and the compile log will be reported back to the application b= y VK_EXT_debug_report if enabled.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pCr= eateInfo must be a valid pointer t= o a valid VkShaderModuleCreateInfo structure

  • If p= Allocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloca= tionCallbacks structure

  • p= ShaderModule must be a valid point= er to a VkShaderModule handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INVALID_SHADER_NV

The VkShaderModuleCreateInfo structure is defined as:

typedef struct VkShaderModuleCr=
eateInfo {
    VkStructureType              sType;
    const void*                  pNext;
    VkShaderModuleCreateFlags    flags;
    size_t                       codeSize;
    const uint32_t*              pCode;
} VkShaderModuleCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • codeSize is the size, in bytes, of the code pointed to by pCode.

  • pCode points to code that is used to create the shader modu= le. The type and format of the code is determined from the content of the memory addressed by pCode.

Valid Usage
  • codeSize must be greater tha= n 0

  • If pCode points to SPIR-V code, codeSize must be a multiple of 4

  • pCode must point to either v= alid SPIR-V code, formatted and packed as described by the Khronos SPIR-V Specification or valid GLSL code which must be written = to the GL_KHR_vulkan_glsl extension specification

  • If pCode points to SPIR-V code, that code must adhere to the validation rules described by the Validation Ru= les within a Module section of the SPIR-V Environment appendix

  • If pCode points to GLSL code, it must= be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification

  • pCode must declare the Shader capability for SPIR-V code

  • pCode must not declare any c= apability that is not supported by the API, as described by the Capabilities s= ection of the SPIR-V Environment appendix

  • If pCode declares any of the capabilities listed as optional in the SPIR-V Environment appendix, the corresponding feature(s) must be enabled.=

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_SHADE= R_MODULE_CREATE_INFO

  • pNext must be NULL or a pointe= r to a valid instance of VkShad= erModuleValidationCacheCreateInfoEXT

  • fla= gs must be 0

  • pCode= must be a valid pointer to an arr= ay of \(codeSize \over 4\) uint32_t values

typedef VkFlags VkShaderModuleCreateFlags;

VkShaderModuleCreateFlags is a bitmask type for setting a m= ask, but is currently reserved for future use.

To use a VkValidationCacheEXT to cache shader = validation results, add a VkShaderModuleValidationCache= CreateInfoEXT to the pNext chain of the VkShaderModuleCreateInfo structure, sp= ecifying the cache object to use.

The VkShaderModuleValidationCacheCreateInfoEXT struct is de= fined as:

typedef struct VkShaderModuleVa=
lidationCacheCreateInfoEXT {
    VkStructureType         sType;
    const void*             pNext;
    VkValidationCacheEXT    validationCache;
} VkShaderModuleValidationCacheCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • validationCache is the validation cache object from which t= he results of prior validation attempts will be written, and to which new validation results for this VkShaderModule will be writ= ten (if not already present).

Valid Usage (Implicit)

To destroy a shader module, call:

void vkDestroyShaderModule(
    VkDevice                                    device,
    VkShaderModule                              shaderModule,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the shader modul= e.

  • shaderModule is the handle of the shader module to destroy.=

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

A shader module can be destroyed while= pipelines created using its shaders are still in use.

Valid Usage
  • If VkAllocationCallbacks were provided when shaderModule= was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when shaderMod= ule was created, pAllocator must= be NULL

Valid Usage (Implicit)
  • device<= /code> must be a valid VkDevice handle

  • If shaderModule is not VK_NULL_HANDLE, shad= erModule must be a valid VkS= haderModule handle

  • If = pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloc= ationCallbacks structure

  • If s= haderModule is a valid handle, it must have been created, allocated, or retrieved from device

Host Synchronization
  • Host access to shaderModule must be externally synchronized

8.2. Shader Execution

At each stage of the pipeline, multiple invocations of a shader may execute simultaneously. Further, invocations of a single shader produced as the result of different commands may execute simultaneously. The relative execution order of invocations of the same shader type is undefined. Shader invocations may complete in a diff= erent order than that in which the primitives they originated from were drawn or dispatched by the application= . However, fragment shader outputs are written to attachments in rasterization order.

The relative order of invocations of different shader types is largely undefined. However, when invoking a shader whose inputs are generated from a previous pipeline stage, the shader invocations from the previous stage are guaranteed to have executed far enough to generate input values for all required inputs.

8.3. Shader Memory Access Orde= ring

The order in which image or buffer memory is read or written by shaders = is largely undefined. For some shader types (vertex, tessellation evaluation, and in some cases, fragment), even the number of shader invocations that may perform loads and stores is undefined.

In particular, the following rules apply:

  • Vertex and tessellation evaluation shaders will be invoked at least once for each unique vertex, as defined in those sections.

  • Fragment shaders will be invoked zero or more times, as defined in that section.

  • The relative order of invocations of the same shader type are undefined. A store issued by a shader when working on primitive B might complete prior to a store for primitive A, even if primitive A is specified prior to primitive B. This applies even to fragment shaders; while fragment shader outputs are always written to the framebuffer in rasterization order, stores executed by fragment shader invocations are not.

  • The relative order of invocations of different shader types is largely undefined.

Note

The above limitations on shader invocation order make some forms of synchronization between shader invocations within a single set of primitive= s unimplementable. For example, having one invocation poll memory written by another invocatio= n assumes that the other invocation has been launched and will complete its writes in finite time.

Stores issued to different memory locations within a single shader invocation may not be visible to other in= vocations, or may not become visible in the order they were performed.

The OpMemoryBarrier instruction ca= n be used to provide stronger ordering of reads and writes performed by a single invocation. OpMemoryBarrier guarantees that any memory transactions issued= by the shader invocation prior to the instruction complete prior to the memory transactions issued after the instruction. Memory barriers are needed for algorithms that require multiple invocations to access the same memory and require the operations to be performed in a partially-defined relative order. For example, if one shader invocation does a series of writes, followed by an OpMemoryBarrier instruction, followed by another write, the= n the results of the series of writes before the barrier become visible to other shader invocations at a time earlier or equal to when the results of the final write become visible to those invocations. In practice it means that another invocation that sees the results of the final write would also see the previous writes. Without the memory barrier, the final write may be visible before the previous writes.

Writes that are the result of shader stores through a variable decorated with Coherent automatically have available writes to the same = buffer, buffer view, or image view made visible to them, and are themselves automatically made available to access by the same buffer, buffer view, or image view. Reads that are the result of shader loads through a variable decorated with Coherent automatically have available writes to the same buffe= r, buffer view, or image view made visible to them. The order that coherent writes to different locations become available is undefined, unless enforced by a memory barrier instruction or other memory dependency.

Note

Explicit memory dependencies must stil= l be used to guarantee availability and visibility for access via other buffers, buffer views, or image views.<= /p>

The built-in atomic memory transaction instructions can be used to read and write a given memory address atomically. While built-in atomic functions issued by multiple shader invocations are executed in undefined order relative to each other, these functions perform both a read and a write of a memory address and guarantee that no other memory transaction will write to the underlying memory between the read and write. Atomic operations ensure automatic availability and visibility for writes and reads in the same way as those to Coherent variables.

Note

Memory accesses performed on different resource descriptors with the sam= e memory backing may not be well-defined ev= en with the Coherent decoration or via atomics, due to things such as image layouts or ownership of the resource - as described in the Synchronization and Cache Control chapter.

Note

Atomics allow shaders to use shared global addresses for mutual exclusio= n or as counters, among other uses.

8.4. Shader Inputs and Outputs

Data is passed into and out of shaders using variables with input or out= put storage class, respectively. User-defined inputs and outputs are connected between stages by matching their Location decorations. Additionally, data can be provided by or = communicated to special functions provided by the execution environment using BuiltIn decoration= s.

In many cases, the same BuiltIn decoration can be used in multiple shader stages with similar meaning. The specific behavior of variables decorated as BuiltIn is doc= umented in the following sections.

8.5. Vertex Shaders

Each vertex shader invocation operates on one vertex and its associated vertex attribute data, and outputs one vertex and associated data. Graphics pipelines must include a vertex = shader, and the vertex shader stage is always the first shader stage in the graphics pipeline.

8.5.1. Vertex Shader Execution

A vertex shader must be executed at le= ast once for each vertex specified by a draw command. If the subpass includes multiple views in its view mask, the shader may be invoked separately for each view. During execution, the shader is presented with the index of the vertex and instance for which it has been invoked. Input variables declared in the vertex shader are filled by the implementation with the values of vertex attributes associated with the invocation being executed.

If the same vertex is specified multiple times in a draw command (e.g. b= y including the same index value multiple times in an index buffer) the implementation may reuse the results of v= ertex shading if it can statically determine that the vertex shader invocations will produce identical results= .

Note

It is implementation-dependent when and if results of vertex shading are reused, and thus how many times the vertex shader will be executed. This is true also if the vertex shader contains stores or atomic operations (see vertexPipeline= StoresAndAtomics).

8.6. Tessellation Control Shaders

The tessellation control shader is used to read an input patch provided = by the application and to produce an output patch. Each tessellation control shader invocation operates on an input patch (after all control points in the patch are processed by a vertex shader) an= d its associated data, and outputs a single control point of the output patch and its associated data, and can also out= put additional per-patch data. The input patch is sized according to the patchControlPoints m= ember of VkPipelineTessellationStateCreateInf= o, as part of input assembly. The size of the output patch is controlled by the OpExecutionMode OutputVertices specified in the tessellation control or tessel= lation evaluation shaders, which must be specifi= ed in at least one of the shaders. The size of the input and output patches must each be greater than zero and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSize.=

8.6.1. Tessellation Contr= ol Shader Execution

A tessellation control shader is invoked at least once for each outp= ut vertex in a patch. If the subpass includes multiple views in its view mask, the shader may be invoked separately for each view.

Inputs to the tessellation control shader are generated by the vertex shader. Each invocation of the tessellation control shader can read the attributes of any incoming vertices and their associated data. The invocations corresponding to a given patch execute logically in parallel, with undefined relative execution order. However, the OpControlBarrier instruction can be used to provide limited control of the execution order by synchronizing invocations within = a patch, effectively dividing tessellation control shader execution into a se= t of phases. Tessellation control shaders will read undefined values if one invocation reads a per-vertex or per-patch attribute written by another invocation at any point during the same phase, or if two invocations attempt to write different values to the same per-patch output in a single phase.

8.7. Tessellation Evaluation Sha= ders

The Tessellation Evaluation Shader operates on an input patch of control points and their associated data, and a single input barycentric coordinate indicating the invocation=E2=80=99s relative position within the subdivided= patch, and outputs a single vertex and its associated data.

8.7.1. Tessellation Ev= aluation Shader Execution

A tessellation evaluation shader is invoked at least once for each uniqu= e vertex generated by the tessellator. If the subpass includes multiple views in its view mask, the shader may be invoked separately for each view.

8.8. Geometry Shaders

The geometry shader operates on a group of vertices and their associated data assembled from a single input primitive, and emits zero or more output primitives and the group of vertices and their associated data required for each output primitive.

8.8.1. Geometry Shader Execution

A geometry shader is invoked at least once for each primitive produced b= y the tessellation stages, or at least once for each primitive generated by primitive assembly when tessellation is not in use. A shader can request that the geometry shader runs multiple instances. A geometry shader is invoked at least once for each instance. If the subpass includes multiple views in its view mask, the shader may be invoked separately for each view.

8.9. Fragment Shaders

Fragment shaders are invoked as the result of rasterization in a graphic= s pipeline. Each fragment shader invocation operates on a single fragment and its associated data. With few exceptions, fragment shaders do not have access to any data associated with other fragments and are considered to execute in isolation of fragment shader invocations associated with other fragments.

8.9.1. Fragment Shader Execution

For each fragment generated by rasterization, a fragment shader may be invoked. A fragment shader must not be invoked if = the Early Per-Fragment Tests cause it to have no coverage. If the subpass includes multiple views in its view mask, the shader may be invoked separately for each view.

Furthermore, if it is determined that a fragment generated as the result= of rasterizing a first primitive will have its outputs entirely overwritten by a fragment generated as the result of rasterizing a second primitive in the same subpass, and the fragment shader used for the fragment has no other side effects, then the fragment shader may not be executed for the fragment from the first primitive.

Relative ordering of execution of different fragment shader invocations = is not defined.

When a primitive (partially or fully) covers a pixel, the number of time= s the fragment shader is invoked is implementation-dependent, but must obey the following constraints:

  • Each covered sample is included in a single fragment shader invocation.<= /p>

  • When sample shading is not enabled, there is at least one fragment shader invocation.

  • When sample shading is enabled, the minimum number of fragment shader invocations is as defined in Sample Shading.

When there is more than one fragment shader invocation per pixel, the association of samples to invocations is implementation-dependent.

In addition to the conditions outlined above for the invocation of a fragment shader, a fragment shader invocation may<= /strong> be produced as a helper invocation. A helper invocation is a fragment shader invocation that is created solely for the purposes of evaluating derivatives for use in non-helper fragment shader invocations. Stores and atomics performed by helper invocations must not have any effect on memory, and values returned by atomic instructions in helper invocations are undefined.

8.9.2. Early Fragment Tests

An explicit control is provided to allow fragment shaders to enable earl= y fragment tests. If the fragment shader specifies the EarlyFragmentTests OpExecutionMode, the per-fragment tests described in Early Fragment Test Mode are performed prior to fragment shader execution. Otherwise, they are performed after fragment shader execution.

If the fragment shader additionally specifies the PostDepthCoverag= e OpExecutionMode, the value of a variable decorated with the SampleMask built-= in reflects the coverage after the early fragment tests. Otherwise, it reflects the coverage before the early fragment tests.

8.10. Compute Shaders

Compute shaders are invoked via vkCmdDispatch and vkCmdDispatchIndirect commands. In general, they have access to similar resources as shader stages executin= g as part of a graphics pipeline.

Compute workloads are formed from groups of work items called workgroups= and processed by the compute shader in the current compute pipeline. A workgroup is a collection of shader invocations that execute the same shader, potentially in parallel. Compute shaders execute in global workgroups which are divided int= o a number of local workgroups with a size that can be set by assigning a value to the LocalSize execution mode or via an object decorat= ed by the WorkgroupSize decoration. An invocation within a local workgroup can share data with other members of the local workgroup through shared variables and issue memory and control flow barriers to synchronize with other members of the local workgroup.

8.11. Interpolation Decoration= s

Interpolation decorations control the behavior of attribute interpolatio= n in the fragment shader stage. Interpolation decorations can be applied = to Input storage class variables in the fragment shader stage=E2=80=99s interface, and control the interpolation behavior of those variables.

Inputs that could be interpolated can = be decorated by at most one of the following decorations:

  • Flat: no interpolation

  • NoPerspective: linear interpolation (for lines and polygons).

Fragment input variables decorated with neither Flat nor NoPerspective use perspective-correct interpolation (for lines and polygons).

The presence of and type of interpolation is controlled by the above interpolation decorations as well as the auxiliary decorations Centro= id and Sample.

A variable decorated with Flat will not be interpolated. Instead, it will have the same value for every fragment within a triangle. This value will come from a single provoking vertex. A variable decorated with Flat can also be decorated with Centroid or Sample, which will mean the same thin= g as decorating it only as Flat.

For fragment shader input variables decorated with neither Centroi= d nor Sample, the assigned variable may be interpolated anywhere within the pixel and a single value may be assigned = to each sample within the pixel.

Centroid and Sample c= an be used to control the location and frequency of the sampling of the decorated fragment shader input. If a fragment shader input is decorated with Centroid, a singl= e value may be assigned to that variable for all = samples in the pixel, but that value must be interpolated to a location = that lies in both the pixel and in the primitive being rendered, including any of the pixel=E2=80=99s samples = covered by the primitive. Because the location at which the variable is interpolated may be different in neighboring pixels, and derivatives may be computed by computing differences between neighboring pixels, derivatives of centroid-sampled inputs may be less accurate than those fo= r non-centroid interpolated variables. The PostDepthCoverage execution mode does not affect the determination of the centroid location. If a fragment shader input is decorated with Sample, a separat= e value must be assigned to that variable for eac= h covered sample in the pixel, and that value must be sampled at the locatio= n of the individual sample. When rasterizationSamples is VK_SAMPLE_COUNT_1_BIT, the pixel center must be used for Centroid, Sample, and undecorated attribute interpolation.

Fragment shader inputs that are signed or unsigned integers, integer vectors, or any double-precision floating-point type must be decorated with Flat.

When the VK_AMD_shader_ex= plicit_vertex_parameter device extension is enabled inputs can be also decorated with= the CustomInterpAMD interpolation decoration, including fragment shader inputs that are signed or unsigned integers, integer vectors, or any double-precision floating-point type. Inputs decorated with CustomInterpAMD can only be accessed by the extended instruction InterpolateAtVertexAMD and allows accessi= ng the value of the input for individual vertices of the primitive.

8.12. Static Use

A SPIR-V module declares a global object in memory using the OpVar= iable instruction, which results in a pointer x to that object. A specific entry point in a SPIR-V module is said to statically use that object if that entry point=E2=80=99s call tree contains a function that con= tains a memory instruction or image instruction with x as an id<= /code> operand. See the =E2=80=9CMemory Instructions=E2=80=9D and =E2=80=9CImage Instructio= ns=E2=80=9D subsections of section 3 =E2=80=9CBinary Form=E2=80=9D of the SPIR-V specification for the= complete list of SPIR-V memory instructions.

Static use is not used to control the behavior of variables with I= nput and Output storage. The effects of those variables are applied based only on whether they are present in a shader entry point=E2=80=99s interface.

8.13. Invocation and Derivative Groups<= /h3>

An invocation group (see the subsection =E2=80=9CControl Flow= =E2=80=9D of section 2 of the SPIR-V specification) for a compute shader is the set of invocations in a single local workgroup. For graphics shaders, an invocation group is an implementation-dependent subset of the set of shader invocations of a given shader stage which are produced by a single drawing command. For indirect drawing commands with drawCount greater than one, invocations from separate draws are in distinct invocation groups.

Note

Because the partitioning of invocations into invocation groups is implementation-dependent and not observable, applications generally need to assume the worst case of all invocations in a draw belonging to a single invocation group.

A derivative group (see the subsection =E2=80=9CControl Flow=E2= =80=9D of section 2 of the SPIR-V 1.00 Revision 4 specification) for a fragment shader is the set of invocations generated by a single primitive (point, line, or triangle), including any helper invocations generated by that primitive. Derivatives are undefined for a sampled image instruction if the instructio= n is in flow control that is not uniform across the derivative group.

8.14. Subgroups

A subgroup (see the subsection ``Control Flow'' of section 2 of= the SPIR-V 1.3 Revision 1 specification) is a set of invocations that can synchronize and share data with each other efficiently. An invocation group is partitioned into one or more subgroups.

Subgroup operations are divided into various categories as described in VkSubgroupFeatureFlagBits.

8.14.1. Basic Subgroup Operations

The basic subgroup operations allow two classes of functionality within shaders - elect and barrier. Invocations within a subgroup can choose = a single invocation to perform some task for the subgroup as a whole using elect. Invocations within a subgroup can perform= a subgroup barrier to ensure the ordering of execution or memory accesses within a subgroup. Barriers can be performed on buffer memor= y accesses, WorkgroupLocal memory accesses, and image memory accesses to ensure that any results written are visible by other invocations within the subgroup. An OpControlBarrier can also= be used to perform a full execution control barrier. A full execution control barrier will ensure that each active invocation within the subgroup reaches a point of execution before any are allowed to continue.

8.14.2. Vote Subgroup Operations

The vote subgroup operations allow invocations within a subgroup to comp= are values across a subgroup. The types of votes enabled are:

  • Do all active subgroup invocations agree that an expression is true?

  • Do any active subgroup invocations evaluate an expression to true?

  • Do all active subgroup invocations have the same value of an expression?=

Note

These operations are useful in combination with control flow in that the= y allow for developers to check whether conditions match across the subgroup and choose potentially faster code-paths in these cases.

8.14.3. Arithmetic Subgroup Operatio= ns

The arithmetic subgroup operations allow invocations to perform scan and reduction operations across a subgroup. For reduction operations, each invocation in a subgroup will obtain the sam= e result of these arithmetic operations applied across the subgroup. For scan operations, each invocation in the subgroup will perform an inclusive or exclusive scan, cumulatively applying the operation across the invocations in a subgroup in linear order. The operations supported are add, mul, min, max, and, or, xor.

8.14.4. Ballot Subgroup Operations

The ballot subgroup operations allow invocations to perform more complex votes across the subgroup. The ballot functionality allows all invocations within a subgroup to provid= e a boolean value and get as a result what each invocation provided as their boolean value. The broadcast functionality allows values to be broadcast from an invocatio= n to all other invocations within the subgroup, given that the invocation to be broadcast from is known at pipeline creation time.

8.14.5. Shuffle Subgroup Operations

The shuffle subgroup operations allow invocations to read values from ot= her invocations within a subgroup.

8.14.6. Shuffle Relative Subgr= oup Operations

The shuffle relative subgroup operations allow invocations to read value= s from other invocations within the subgroup relative to the current invocation in the group. The relative operations supported allow data to be shifted up and down through the invocations within a subgroup.

8.14.7. Clustered Subgroup Operations=

The clustered subgroup operations allow invocations to perform an operat= ion among partitions of a subgroup, such that the operation is only performed within the subgroup invocations within a partition. The partitions for clustered subgroup operations are consecutive power-of-two size groups of invocations and the cluster size must be known at pipeline creation time. The operations supported are add, mul, min, max, and, or, xor.

8.14.8. Quad Subgroup Operations

The quad subgroup operations allow clusters of 4 invocations (a quad), t= o share data efficiently with each other.

8.14.9. Partitioned Subgroup Operat= ions

The partitioned subgroup operations allow invocations to perform an operation among partitions of a subgroup, such that the operation is only performed within the subgroup invocations within a partition. The partitions for partitioned subgroup operations can group the invocations into arbitrary subsets and can be computed at runtime. The operations supported are add, mul, min, max, and, or, xor.

8.15. Validation Cache

Validation cache objects allow the result of internal validation to be reused, both within a single application run and between multiple runs. Reuse within a single run is achieved by passing the same validation cache object when creating supported Vulkan objects. Reuse across runs of an application is achieved by retrieving validation cache contents in one run of an application, saving the contents, and using them to preinitialize a validation cache on a subsequent run. The contents of the validation cache objects are managed by the validation layers. Applications can manage the host memory c= onsumed by a validation cache object and control the amount of data retrieved from a validation cache object.

Validation cache objects are represented by VkValidationCacheEXT handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkValidationCacheEXT)

To create validation cache objects, call:

VkResult vkCreateV=
alidationCacheEXT(
    VkDevice                                    device,
    const VkValidationCacheCreateInfoEXT* =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkValidationCacheEXT*                       pValidationCache);
  • device is the logical device that creates the validation ca= che object.

  • pCreateInfo is a pointer to a VkValidationCacheCreateInfoEXT structure that contains the initial parameters for the validation cache object.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pValidationCache is a pointer to a Vk= ValidationCacheEXT handle in which the resulting validation cache object is returned.

Note

Applications can track and manage the = total host memory size of a validation cache object using the pAllocator. Applications can limit the amount of data= retrieved from a validation cache object in vkGetValidationCacheDataEXT. Implementations should not internally lim= it the total number of entries added to a validation cache object or the total host memory consumed.

Once created, a validation cache can b= e passed to the vkCreateShaderModule command as part of the VkShaderModuleCreateInfo pNext chain. If a VkShaderModuleValidationCacheCreateInfoEXT object is part= of the VkShaderModuleCreateInfo::pNext chain, and its validationCache field is not VK_NULL_HANDLE, the implementation will query it for possible reuse opportunities and update it with new content. The use of the validation cache object in these commands is internally synchronized, and the same validation cache object can be used in multiple threads simultaneously.

Note

Implementations should make every effo= rt to limit any critical sections to the actual accesses to the cache, which is expected to be significantly shorter than the duration of the vkCreateShaderModule command.=

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkValidationCacheCreateInfoEXT structure is defined as:=

typedef struct VkValidationCach=
eCreateInfoEXT {
    VkStructureType                    sType;
    const void*                        pNext;
    VkValidationCacheCreateFlagsEXT    flags;
    size_t                             initialDataSize;
    const void*                        pInitialData;
} VkValidationCacheCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • initialDataSize is the number of bytes in pInitialDat= a. If initialDataSize is zero, the validation cache will initiall= y be empty.

  • pInitialData is a pointer to previously retrieved validatio= n cache data. If the validation cache data is incompatible (as defined below) with the device, the validation cache will be initially empty. If initialDataSize is zero, pInitialData is ignor= ed.

Valid Usage
  • If initialDataSize is not 0, it must be equal to the size of pInitialData, as returned by vkGetValidationCacheDataEXT= when pInitialData was originally retrieved

  • If initialDataSize is not 0, pInitialData must have been retrieved from a previous call to vkGetValidationCacheDataEXT<= /p>

Valid Usage (Implicit)
typedef VkFlags VkValidationCacheCreateFlagsEXT;

VkValidationCacheCreateFlagsEXT is a bitmask type for setti= ng a mask, but is currently reserved for future use.

Data can be retrieved from a validatio= n cache object using the command:

VkResult vkGetVali=
dationCacheDataEXT(
    VkDevice                                    device,
    VkValidationCacheEXT                        validationCache,
    size_t*                                     pDataSize,
    void*                                 =
      pData);
  • device is the logical device that owns the validation cache= .

  • validationCache is the validation cache to retrieve data fr= om.

  • pDataSize is a pointer to a value related to the amount of = data in the validation cache, as described below.

  • pData is either NULL or a pointer to a buffer.=

If pData is NULL, then the maximum size of the= data that can be retrieved from the validation cache, in bytes, is returned in pDataSize. Otherwise, pDataSize must po= int to a variable set by the user to the size of the buffer, in bytes, pointed to by pData, and on retu= rn the variable is overwritten with the amount of data actually written to pData.

If pDataSize is less than the maximum size that can be retrieved by the validation cache, at most pDataSize bytes will be written = to pData, and vkGetValidationCacheDataEXT will retur= n VK_INCOMPLETE. Any data written to pData is valid and can be provided as the pInitialData member of the VkValidationCacheCreateInfoEX= T structure passed to vkCreateValidationCacheEXT.

Two calls to vkGetValidationCacheDataEXT with the same para= meters must retrieve the same data unless a comm= and that modifies the contents of the cache is called between them.

Applications can store the data retrie= ved from the validation cache, and use these data, possibly in a future run of the application, to populate ne= w validation cache objects. The results of validation, however, may d= epend on the vendor ID, device ID, driver version, and other details of the device. To enable applications to detect when previously retrieved data is incompatible with the device, the initial bytes written to pData must be a header consisting of the following members:

Table 11. Layout for validation cache header versi= on VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT
Offset Size Meaning

0

4

len= gth in bytes of the entire validation cache header written as a stream of bytes, with the least significant byte first

4

4

a <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kValidationCacheHeaderVersionEXT">VkValidationCacheHeaderVersionEXT val= ue written as a stream of bytes, with the least significant byte first

8

VK_UUID_SIZE

a l= ayer commit ID expressed as a UUID, which uniquely identifies the version of the validation layer= s used to generate these validation results

The first four bytes encode the length of the entire validation cache header, in bytes. This value includes all fields in the header including the validation cache version field and the size of the length field.

The next four bytes encode the validation cache version, as described fo= r VkValidationCacheHeaderVersionEXT. A consumer of the validation cache should= use the cache version to interpret the remainder of the cache header.

If pDataSize is less than what is necessary to store this h= eader, nothing will be written to pData and zero will be written to pDataSize.

Valid Usage (Implicit)
  • d= evice must be a valid VkDevi= ce handle

  • validationCache must be a = valid VkValidationCacheEXT handle

  • pDataSize must be a valid pointe= r to a size_t value

  • If the v= alue referenced by pDataSize is not 0, and = pData is not NULL, pData must be a valid pointer to an array of pDataSize bytes

  • <= code>validationCache must have bee= n created, allocated, or retrieved from device

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Possible values of the second group of four bytes in the header returned= by vkGetValidationCacheDataEXT, encoding the = validation cache version, are:

typedef enum VkValidationCacheH=
eaderVersionEXT {
    VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT =3D =
1,
} VkValidationCacheHeaderVersionEXT;
  • VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT specifies versio= n one of the validation cache.

To destroy a validation cache, call:

void vkDestroyValidationCacheEXT(
    VkDevice                                    device,
    VkValidationCacheEXT                        validationCache,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the validation c= ache object.

  • validationCache is the handle of the validation cache to de= stroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • If VkAllocationCallbacks were provided when validationCa= che was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when validationCache was created, pAllocator must be NULL

Valid Usage (Implicit)
  • d= evice must be a valid VkDevi= ce handle

  • If validationCache is not VK_NULL_HANDLE= , validationCache must be a = valid VkValidationCacheEXT handle

  • If = pAllocator is not NULL, pAllocator <= strong class=3D"purple">must be a valid pointer to a valid V= kAllocationCallbacks structure

  • I= f validationCache is a valid handle, it must have been created, allocated, or retrieved from devi= ce

Host Synchronization
  • Host access to validationCache mus= t be externally synchronized

9. Pipelines

The following figure shows a block diagram = of the Vulkan pipelines. Some Vulkan commands specify geometric objects to be drawn or computational work to be performed, while others specify state controlling how objects ar= e handled by the various pipeline stages, or control data transfer between memory organized as images and buffers. Commands are effectively sent through a processing pipeline, either a graphics pipeline or a compute pipeline.

The first stage of the graphics pipeline (Input Assembler) assembles vertices to form geometric primitives such as points, lines, and triangles, based on a requested primitive topology. In the next stage (Vertex Shader) vertices can be transformed, computing positions and attributes for each vertex. If tessellation and/or geometry shaders are supported, they can then generate multipl= e primitives from a single input primitive, possibly changing the primitive topology or generating additiona= l attribute data in the process.

The final resulting primitives are clipped = to a clip volume in preparation for the next stage, Rasterization= . The rasterizer produces a series of framebuffer addresses and values using = a two-dimensional description of a point, line segment, or triangle. Each fragment so produced is fed to the next stage (Fragment Shader) that performs operations on individual fragments before they finally alter the framebuffer. These operations include conditional updates into the framebuffer based on incoming and previously stored depth values (to effect depth buffering), blending of incoming fragment col= ors with stored colors, as well as masking, stenciling, and other logical operations on fragment values.

Framebuffer operations read and write the color and depth/stencil attachments of the framebuffer for a given subpass of a render pass instance. The attachments can be used as input atta= chments in the fragment shader in a later subpass of the same render pass.

The compute pipeline is a separate pipeline from = the graphics pipeline, which operates on one-, two-, or three-dimensional workgroups which can read from and write = to buffer and image memory.

This ordering is meant only as a tool for describing Vulkan, not as a st= rict rule of how Vulkan is implemented, and we present it only as a means to organize the various operations of the pipelines. Actual ordering guarantees between pipeline stages are explained in detail in the synchronization chapter.<= /p>

3D"pipeline"
Figure 2. Block diagram of the Vulkan pipeline

Each pipeline is controlled by a monolithic object created from a description of all of the shader stages and any relevant fixed-function stages. Linking the whole pipeline together allows the optimization of shaders based on their input/outputs and eliminates expensive draw time state validation.

A pipeline object is bound to the current state using vkCmdBindPipeline. Any pipeline object state that is specified as dyn= amic is not applied to the current state when the pipeline object is bound, but is instead set by dynamic state setting commands.

No state, including dynamic state, is inherited from one command buffer = to another.

Compute and graphics pipelines are each represented by VkPipeline<= /code> handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkPipeline)

9.1. Compute Pipelines

Compute pipelines consist of a single static compute shader stage and th= e pipeline layout.

The compute pipeline represents a compute shader and is created by calli= ng vkCreateComputePipelines with module and pN= ame selecting an entry point from a shader module, where that entry point defines a valid compute shader, in the VkPipelineShaderStageCreateInfo structu= re contained within the VkComputePipelineCreateInfo structure.

To create compute pipelines, call:

VkResult vkCreateC=
omputePipelines(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    uint32_t                                    createInfoCount,
    const VkComputePipelineCreateInfo*    =
      pCreateInfos,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkPipeline*                                 pPipelines);
  • device is the logical device that creates the compute pipel= ines.

  • pipelineCache is either VK_NULL_HANDLE,= indicating that pipeline caching is disabled; or the handle of a valid pipeline cache object, in which case use of that cache is enabled for the duration of the command.

  • createInfoCount is the length of the pCreateInfos and pPipelines arrays.

  • pCreateInfos is an array of Vk= ComputePipelineCreateInfo structures.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pPipelines is a pointer to an array in which the resulting = compute pipeline objects are returned.

    editing-note

    TODO (Jon) - Should we say something like =E2=80=9Cthe i=E2=80=99th elem= ent of the pPipelines array is created based on the corresponding element= of the pCreateInfos array=E2=80=9D? Also for vkCreateGraphicsPipelines below.

Valid Usage
  • If the flags member of any element of pCreateInfos contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the basePipelineIndex member of that same element is not -1<= /code>, basePipelineIndex must be le= ss than the index into pCreateInfos that corresponds to that element

  • If the flags member of any element of pCreateInfos contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, the base pipeline must have been created with the VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT flag set

Valid Usage (Implicit)
  • devi= ce must be a valid VkDevice<= /code> handle

  • If = pipelineCache is not VK_NULL_HANDLE, pipelineCache must be a valid VkPipelineCache handle

  • pCreateInfos must be a valid poi= nter to an array of createInfoCount valid VkComputePipel= ineCreateInfo structures

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAl= locationCallbacks structure

  • = pPipelines must be a valid pointer= to an array of createInfoCount VkPipeline handle= s

  • = createInfoCount must be gre= ater than 0

  • If pipelineCache is a valid handle, it must= have been created, allocated, or retrieved from device

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INVALID_SHADER_NV

The VkComputePipelineCreateInfo structure is defined as:

typedef struct VkComputePipelin=
eCreateInfo {
    VkStructureType                    sType;
    const void*                        pNext;
    VkPipelineCreateFlags              flags;
    VkPipelineShaderStageCreateInfo    stage;
    VkPipelineLayout                   layout;
    VkPipeline                         basePipelineHandle;
    int32_t                            basePipelineIndex;
} VkComputePipelineCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkPipelineC= reateFlagBits specifying how the pipeline will be generated.

  • stage is a VkPipelineShade= rStageCreateInfo describing the compute shader.

  • layout is the description of binding locations used by both= the pipeline and descriptor sets used with the pipeline.

  • basePipelineHandle is a pipeline to derive from

  • basePipelineIndex is an index into the pCreateInfos parameter to use as a pipeline to derive from

The parameters basePipelineHandle and basePipelineInd= ex are described in more detail in Pipeline Derivatives.

stage points to a structure of type VkPipelineShaderStageCreateInfo.

Valid Usage
  • If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT<= /code> flag, and basePipelineIndex is -1, basePipelineHandle must be a valid handle to a compute VkPipeline

  • If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT<= /code> flag, and basePipelineHandle is VK_NULL_HANDLE= , basePipelineIndex must be a = valid index into the calling command=E2=80=99s pCreateInfos parameter

  • If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT<= /code> flag, and basePipelineIndex is not -1, basePipelineHandl= e must be VK_NULL_HANDLE

  • If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT<= /code> flag, and basePipelineHandle is not VK_NULL_HA= NDLE, basePipelineIndex must be -1=

  • The stage member of stage must be VK_SHADER_STAGE_COMPUTE_BIT

  • The shader code for the entry point identified by stage and th= e rest of the state identified by this structure mus= t adhere to the pipeline linking rules described in the Shader Interfaces chapter

  • layout must be consistent with the layout of the compute shader specified in stage

  • The number of resources in layout accessible to the compute sh= ader stage must be less than or equal to VkPhysicalDeviceLimits::maxPerStageResources

Valid Usage (Implicit)
  • sType<= /code> must be VK_STRUCTURE_TYPE_CO= MPUTE_PIPELINE_CREATE_INFO

  • pNext<= /code> must be NULL

  • fl= ags must be a valid combination of= VkPipelineCreateFlagBits values

  • st= age must be a valid VkPipeli= neShaderStageCreateInfo structure

  • l= ayout must be a valid VkPipe= lineLayout handle

  • Both of basePipelineHandle, and layout that are valid handle= s must have been created, allocated, or r= etrieved from the same VkDevice

The VkPipelineShaderStageCreateInfo structure is defined as= :

typedef struct VkPipelineShader=
StageCreateInfo {
    VkStructureType                     sType;
    const void*                         pNext;
    VkPipelineShaderStageCreateFlags    flags;
    VkShaderStageFlagBits               stage;
    VkShaderModule                      module;
    const =
char*                         pName;
    const VkSpecializationInfo*         pS=
pecializationInfo;
} VkPipelineShaderStageCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • stage is a VkShaderStageFlagBits= value specifying a single pipeline stage.

  • module is a VkShaderModule object that = contains the shader for this stage.

  • pName is a pointer to a null-terminated UTF-8 string specif= ying the entry point name of the shader for this stage.

  • pSpecializationInfo is a pointer to V= kSpecializationInfo, as described in Specialization Constants, and can be NULL.

Valid Usage
  • If the geometry shaders feature is not enabled, stage must not = be VK_SHADER_STAGE_GEOMETRY_BIT

  • If the tessellation shaders feature is not enabled, stage must not be VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT

  • stage must not be VK_S= HADER_STAGE_ALL_GRAPHICS, or VK_SHADER_STAGE_ALL

  • pName must be the name of an= OpEntryPoint in module with an execution model that matches stage

  • If the identified entry point includes any variable in its interface that is declared with the ClipDistance BuiltIn de= coration, that variable must not have an array size= greater than VkPhysicalDeviceLimits::maxClipDistances

  • If the identified entry point includes any variable in its interface that is declared with the CullDistance BuiltIn de= coration, that variable must not have an array size= greater than VkPhysicalDeviceLimits::maxCullDistances

  • If the identified entry point includes any variables in its interface that are declared with the ClipDistance or CullDistance<= /code> BuiltIn decoration, those variables m= ust not have array sizes which sum to more than VkPhysicalDeviceLimits::maxCombinedClipAndCullDistances<= /code>

  • = If the identified entry point includes any variable in its interface that is declared with the SampleMask BuiltIn deco= ration, that variable must not have an array size grea= ter than VkPhysicalDeviceLimits::maxSampleMaskWords

  • If stage is VK_SHADER_STAGE_VERTEX_BIT, the ident= ified entry point must not include any input variable= in its interface that is decorated with CullDistance

  • If stage is VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, and the identifie= d entry point has an OpExecutionMode instruction that specifies = a patch size with OutputVertices, the patch size must be greater than 0 and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSize<= /p>

  • If stage is VK_SHADER_STAGE_GEOMETRY_BIT, the ide= ntified entry point must have an OpExecutio= nMode instruction that specifies a maximum output vertex count that is greater than 0= and less than or equal to VkPhysicalDeviceLimits::maxGeometryOutputVertices=

  • If stage is VK_SHADER_STAGE_GEOMETRY_BIT, the ide= ntified entry point must have an OpExecutio= nMode instruction that specifies an invocation count that is greater than 0 and less = than or equal to VkPhysicalDeviceLimits::maxGeometryShaderInvocations

  • If stage is VK_SHADER_STAGE_GEOMETRY_BIT, and the= identified entry point writes to Layer for any primitive, it must write the same value to Layer for all vertices of a given primitive

  • If stage is VK_SHADER_STAGE_GEOMETRY_BIT, and the= identified entry point writes to ViewportIndex for any primitive, it must write the same value to ViewportIndex for all vertices of a gi= ven primitive

  • If stage is VK_SHADER_STAGE_FRAGMENT_BIT, the ide= ntified entry point must not include any output v= ariables in its interface decorated with CullDistance

  • If stage is VK_SHADER_STAGE_FRAGMENT_BIT, and the= identified entry point writes to FragDepth in any execution path, it must write to FragDepth in all execution paths

  • If stage is VK_SHADER_STAGE_FRAGMENT_BIT, and the= identified entry point writes to FragStencilRefEXT in any execution path,= it must write to FragStencilRefEXT in all execution paths

Valid Usage (Implicit)
  • sT= ype must be VK_STRUCTURE_TYP= E_PIPELINE_SHADER_STAGE_CREATE_INFO

  • pN= ext must be NULL

  • flags must be 0

  • stage must be a valid VkShaderStageFlagBits value

  • module must be a valid Vk= ShaderModule handle

  • pName must be a null-terminated = UTF-8 string

  • If pSpecializationInfo is not NULL, pSpecializationInfo must be a v= alid pointer to a valid VkSpecializationInfo structure

typedef VkFlags VkPipelineShaderStageCreateFlags;

VkPipelineShaderStageCreateFlags is a bitmask type for sett= ing a mask, but is currently reserved for future use.

Commands and structures which need to specify one or more shader stages = do so using a bitmask whose bits correspond to stages. Bits which can be set to specify shader s= tages are:

typedef enum VkShaderStageFlagB=
its {
    VK_SHADER_STAGE_VERTEX_BIT =3D 0x00000001,
    VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT =3D 0x0000=
0002,
    VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT =3D 0x0=
0000004,
    VK_SHADER_STAGE_GEOMETRY_BIT =3D 0x00000008,
    VK_SHADER_STAGE_FRAGMENT_BIT =3D 0x00000010,
    VK_SHADER_STAGE_COMPUTE_BIT =3D 0x00000020,
    VK_SHADER_STAGE_ALL_GRAPHICS =3D 0x0000001F,
    VK_SHADER_STAGE_ALL =3D 0x7FFFFFFF,
} VkShaderStageFlagBits;
  • VK_SHADER_STAGE_VERTEX_BIT specifies the vertex stage.

  • VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT specifies the tessellation control stage.

  • VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT specifies the tessellation evaluation stage.

  • VK_SHADER_STAGE_GEOMETRY_BIT specifies the geometry stage.<= /p>

  • VK_SHADER_STAGE_FRAGMENT_BIT specifies the fragment stage.<= /p>

  • VK_SHADER_STAGE_COMPUTE_BIT specifies the compute stage.

  • VK_SHADER_STAGE_ALL_GRAPHICS is a combination of bits used = as shorthand to specify all graphics stages defined above (excluding the compute stage).

  • VK_SHADER_STAGE_ALL is a combination of bits used as shorth= and to specify all shader stages supported by the device, including all additional stages which are introduced by extensions.

typedef VkFlags VkShaderStageFlags;

VkShaderStageFlags is a bitmask type for setting a mask of = zero or more VkShaderStageFlagBits.

9.2. Graphics Pipelines

Graphics pipelines consist of multiple shader stages, multiple fixed-function pipeline stages, and a pipeline layout.

To create graphics pipelines, call:

VkResult vkCreateG=
raphicsPipelines(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    uint32_t                                    createInfoCount,
    const VkGraphicsPipelineCreateInfo*   =
      pCreateInfos,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkPipeline*                                 pPipelines);
  • device is the logical device that creates the graphics pipe= lines.

  • pipelineCache is either VK_NULL_HANDLE,= indicating that pipeline caching is disabled; or the handle of a valid pipeline cache object, in which case use of that cache is enabled for the duration of the command.

  • createInfoCount is the length of the pCreateInfos and pPipelines arrays.

  • pCreateInfos is an array of V= kGraphicsPipelineCreateInfo structures.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pPipelines is a pointer to an array in which the resulting graphics pipeline objects are returned.

The VkGraphicsPipelineCreateInfo struc= ture includes an array of shader create info structures containing all the desired active shader stages, as well as creation info to define all relevant fixed-function stages, and a pipeline layout.

Valid Usage
  • If the flags member of any element of pCreateInfos contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the basePipelineIndex member of that same element is not -1<= /code>, basePipelineIndex must be le= ss than the index into pCreateInfos that corresponds to that element

  • If the flags member of any element of pCreateInfos contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, the base pipeline must have been created with the VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT flag set

Valid Usage (Implicit)
  • dev= ice must be a valid VkDevice= handle

  • If= pipelineCache is not VK_NULL_HANDLE, pipelineCache must be a valid VkPipelineCache handle

  • pCreateInfos must be a valid po= inter to an array of createInfoCount valid VkGraphicsPip= elineCreateInfo structures

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkA= llocationCallbacks structure

  • pPipelines must be a valid pointe= r to an array of createInfoCount VkPipeline handl= es

  • createInfoCount must be gr= eater than 0

  • If pipelineCache is a valid handle, it mus= t have been created, allocated, or retrieved from device

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INVALID_SHADER_NV

The VkGraphicsPipelineCreateInfo structure is defined as:

typedef struct VkGraphicsPipeli=
neCreateInfo {
    VkStructureType                                  sType;
    const void*                                      pNext;
    VkPipelineCreateFlags                            flags;
    uint32_t                                         stageCount;
    const VkPipelineShaderStageCreateInfo*=
           pStages;
    const VkPipelineVertexInputStateCreate=
Info*      pVertexInputState;
    const VkPipelineInputAssemblyStateCrea=
teInfo*    pInputAssemblyState;
    const VkPipelineTessellationStateCreat=
eInfo*     pTessellationState;
    const VkPipelineViewportStateCreateInf=
o*         pViewportState;
    const VkPipelineRasterizationStateCrea=
teInfo*    pRasterizationState;
    const VkPipelineMultisampleStateCreate=
Info*      pMultisampleState;
    const VkPipelineDepthStencilStateCreat=
eInfo*     pDepthStencilState;
    const VkPipelineColorBlendStateCreateI=
nfo*       pColorBlendState;
    const VkPipelineDynamicStateCreateInfo=
*          pDynamicState;
    VkPipelineLayout                                 layout;
    VkRenderPass                                     renderPass;
    uint32_t                                         subpass;
    VkPipeline                                       basePipelineHandle;
    int32_t                                          basePipelineIndex;
} VkGraphicsPipelineCreateInfo;

The parameters basePipelineHandle and basePipelineInd= ex are described in more detail in Pipeline Derivatives.

pStages points to an array of VkPipelineShaderStageCreateInfo structures, which were previously described in Compute Pipelines.

pDynamicState points to a structure of type VkPipelineDynamicStateCreateInfo.

If any shader stage fails to compile, the compile log will be reported back to the application, and VK_ERROR_INVALID_SHADER_NV will be generated.

Valid Usage
  • If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT<= /code> flag, and basePipelineIndex is -1, basePipelineHandle must be a valid handle to a graphics VkPipeline

  • If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT<= /code> flag, and basePipelineHandle is VK_NULL_HANDLE= , basePipelineIndex must be a = valid index into the calling command=E2=80=99s pCreateInfos parameter

  • If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT<= /code> flag, and basePipelineIndex is not -1, basePipelineHandl= e must be VK_NULL_HANDLE

  • If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT<= /code> flag, and basePipelineHandle is not VK_NULL_HA= NDLE, basePipelineIndex must be -1=

  • The stage member of each element of pStages must be unique

  • The stage member of one element of pStages must be VK_SHADER_STAGE_VERTEX_BIT

  • The stage member of each element of pStages must not be VK_SHADER_STAGE_COMPUTE_BIT

  • If pStages includes a tessellation control shader stage, it must include a tessellation evaluation shader stage

  • If pStages includes a tessellation evaluation shader stage, it must include a tessellation control shade= r stage

  • If pStages includes a tessellation control shader stage and a tessellation evaluation shader stage, pTessellationState must be a valid pointer to a valid VkPipelineTessellationStateCreateInfo structure

  • If pStages includes tessellation shader stages, the shader cod= e of at least one stage must contain an = OpExecutionMode instruction that specifies the type of subdivision in the pipeline

  • If pStages includes tessellation shader stages, and the shader code of both stages contain an OpExecutionMode instruction tha= t specifies the type of subdivision in the pipeline, they must both specify the same subdivision mode

  • If pStages includes tessellation shader stages, the shader cod= e of at least one stage must contain an = OpExecutionMode instruction that specifies the output patch size in the pipeline

  • If pStages includes tessellation shader stages, and the shader code of both contain an OpExecutionMode instruction that speci= fies the out patch size in the pipeline, they must both specify the same patch size

  • If pStages includes tessellation shader stages, the topo= logy member of pInputAssembly must be VK_PRIMITIVE_TOPOLOGY_PATCH_LIST

  • If the topology member of pInputAssembly is VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pStages must include tessellation shader stages

  • If pStages includes a geometry shader stage, and does not incl= ude any tessellation shader stages, its shader code mu= st contain an OpExecutionMode instruction that specifies an input primitive = type that is compatible with the primitive topology specified in pInputAssembly

  • If pStages includes a geometry shader stage, and also includes tessellation shader stages, its shader code must contain an OpExecutionMode instruction that specifies an input primitive = type that is compatible with the primitive topology that is output by the tessellation stages

  • If pStages includes a fragment shader stage and a geometry sha= der stage, and the fragment shader code reads from an input variable that is decorated with PrimitiveID, then the geometry shader code must write to a matching output variable, decorated with PrimitiveID, in all execution paths

  • If pStages includes a fragment shader stage, its shader code <= strong class=3D"purple">must not read from any input attachment that is defined as VK_ATTACHMENT_UNUSED in subpass

  • The shader code for the entry points identified by pStages, an= d the rest of the state identified by this structure must adhere to the pipeline linking rules described in the Shader Interfaces chapter

  • If rasterization is not disabled and subpass uses a depth/sten= cil attachment in renderPass that has a layout of VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL in the VkAttachmentReference defined by subpass, = the depthWriteEnable member of pDepthStencilState must be VK_FALSE

  • If rasterization is not disabled and subpass uses a depth/sten= cil attachment in renderPass that has a layout of VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL in the VkAttachmentReference defined by subpass, = the failOp, passOp and depthFailOp membe= rs of each of the front and back members of pDepthStencilStat= e must be VK_STENCIL_OP_KEEP

  • If rasterization is not disabled and the subpass uses color attachments, then for each color attachment in the subpass the blendEnable member of the corresponding element of the pAttachment member = of pColorBlendState must be VK_FALSE if the attached image=E2=80=99s format features does not contain the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT.

  • If rasterization is not disabled and the subpass uses color attachments, the attachmentCount member of pColorBlendState must be equal to the colorAttachmentCount used to create subpass=

  • If no element of the pDynamicStates member of pDynamicSt= ate is VK_DYNAMIC_STATE_VIEWPORT, the pViewports memb= er of pViewportState must be a val= id pointer to an array of pViewportState::viewportCount valid VkViewp= ort structures

  • If no element of the pDynamicStates member of pDynamicSt= ate is VK_DYNAMIC_STATE_SCISSOR, the pScissors member= of pViewportState must be a val= id pointer to an array of pViewportState::scissorCount VkRect2D structures

  • If the wide lines feature is not enabled, and no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_LINE_WIDTH, the lineWidth member= of pRasterizationState must be = 1.0

  • If the rasterizerDiscardEnable member of pRasterizationS= tate is VK_FALSE, pViewportState must be a valid pointer to a valid VkPipelineViewportStateCreateInfo structure

  • If the rasterizerDiscardEnable member of pRasterizationS= tate is VK_FALSE, pMultisampleState must be a valid pointer to a valid VkPipelineMultisampleStateCreateInfo structure

  • If the rasterizerDiscardEnable member of pRasterizationS= tate is VK_FALSE, and subpass uses a depth/stencil att= achment, pDepthStencilState must be a= valid pointer to a valid VkPipelineDepthStencilStateCreateInfo structure

  • If the rasterizerDiscardEnable member of pRasterizationS= tate is VK_FALSE, and subpass uses color attachments, pColorBlendState must be a v= alid pointer to a valid VkPipelineColorBlendStateCreateInfo structure

  • If the depth bias clamping feature is not enabled, no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_DEPTH_BIAS, and the depthBiasEnable member of pRasterizationState is VK_TRUE, the dept= hBiasClamp member of pRasterizationState must be 0.0

  • If the VK_EXT_depth_range_unrestrict= ed extension is not enabled and no element of the pDynamicStates member of pDynamicS= tate is VK_DYNAMIC_STATE_DEPTH_BOUNDS, and the depthBoundsTestEnable member of pDepthStencilState is VK_TRUE, the minDepthBounds and maxDepthBou= nds members of pDepthStencilState must b= e between 0.0 and 1.0, inclusive

  • If no element of the pDynamicStates member of pDynamicSt= ate is VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, and the sampleLocationsEnable member of a VkPipelineSampleLocationsState= CreateInfoEXT structure chained to the pNext chain of pMultisampleState is VK_= TRUE, sampleLocationsInfo.sampleLocationGridSize.width must evenly divide VkMultisamplePropertiesEXT::sampleLoc= ationGridSize.width as returned by vkGetPhysicalDevic= eMultisamplePropertiesEXT with a samples parameter equaling rasterizationSamples

  • If no element of the pDynamicStates member of pDynamicSt= ate is VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, and the sampleLocationsEnable member of a VkPipelineSampleLocationsState= CreateInfoEXT structure chained to the pNext chain of pMultisampleState is VK_= TRUE, sampleLocationsInfo.sampleLocationGridSize.height must evenly divide VkMultisamplePropertiesEXT::sampleLoc= ationGridSize.height as returned by vkGetPhysicalDevic= eMultisamplePropertiesEXT with a samples parameter equaling rasterizationSamples

  • If no element of the pDynamicStates member of pDynamicSt= ate is VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, and the sampleLocationsEnable member of a VkPipelineSampleLocationsState= CreateInfoEXT structure chained to the pNext chain of pMultisampleState is VK_= TRUE, sampleLocationsInfo.sampleLocationsPerPixel must equal rasterizationSamples

  • = If the sampleLocationsEnable member of a VkPipelineSampleLocationsState= CreateInfoEXT structure chained to the pNext chain of pMultisampleState is VK_= TRUE, the fragment shader code must not statically = use the extended instruction InterpolateAtSample

  • layout must be consistent with all shaders specified in pStages

  • If subpass uses color and/or depth/stencil attachments, then t= he rasterizationSamples member of pMultisampleState = must equal the maximum of the sample counts of those subpass attachments

  • If subpass has a depth/stencil attachment and depth test, sten= cil test, or depth bounds test are enabled, then the rasterizationSamples member of pMultisampleState = must be the same as the sample count of the depth/stencil attachment

  • If subpass has any color attachments, then the rasterizationSamples member of pMultisampleState = must be greater than or equal to the sample count for those subpass attachments

  • If subpass does not use any color and/or depth/stencil attachments, then the rasterizationSamples member of pMultisampleState must follo= w the rules for a zero-attachment subpass

  • subpass must be a valid subp= ass within renderPass

  • If the renderPass has multiview enabled and subpass has more than one bit set in the view mask and multiviewTessellationShader is not enabled, then pStages must not include tessellation shaders.

  • If the renderPass has multiview enabled and subpass has more than one bit set in the view mask and multiviewGeometryShader = is not enabled, then pStages must not include a geometry shader.

  • If the renderPass has multiview enabled and subpass has more than one bit set in the view mask, shaders in the pipeline must not write to the Layer built-in output

  • If the renderPass has multiview enabled, then all shaders must not include variables decorated with the Layer built-in decora= tion in their interfaces.

  • flags must not contain the <= code>VK_PIPELINE_CREATE_DISPATCH_BASE flag.

  • If pStages includes a fragment shader stage and an input attachment was referenced by the VkRenderPassInputAttachmentAsp= ectCreateInfo at renderPass create time, its shader code must not rea= d from any aspect that was not specified in the aspectMask of the corresponding VkInputAttachmentAspectReference stru= cture.

  • The number of resources in layout accessible to each shader st= age that is used by the pipeline must be less= than or equal to VkPhysicalDeviceLimits::maxPerStageResources

  • If no element of the pDynamicStates member of pDynamicSt= ate is VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, and the viewportWScalingEnable member of a VkPipelineViewportWScalingStat= eCreateInfoNV structure, chained to the pNext chain of pViewportState, is VK_TR= UE, the pViewportWScalings member of the VkPipelineViewportWScalingStat= eCreateInfoNV must be a pointer to an array of VkPipelineViewportWScalingStat= eCreateInfoNV::viewportCount valid VkViewportWScalingNV structures

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_G= RAPHICS_PIPELINE_CREATE_INFO

  • pNext= must be NULL or a po= inter to a valid instance of = VkPipelineDiscardRectangleStateCreateInfoEXT

  • f= lags must be a valid combination o= f VkPipelineCreateFlagBits values

  • pStages must be a valid pointer t= o an array of stageCount valid VkPipelineShaderStageCrea= teInfo structures

  • = pVertexInputState must = be a valid pointer to a valid VkPipelineVertexInputStateCreateInfo structure

  • pInputAssemblyState must be a valid pointer to a valid VkPipelineInputAssemblyStateCreateI= nfo structure

  • pRasterizationState must be a valid pointer to a valid VkPipelineRasterizationStateCreateI= nfo structure

  • = If pDynamicState is not NULL, pDynamicStat= e must be a valid pointer to a val= id VkPipelineDynamicStateCreateInfo structure

  • = layout must be a valid VkPip= elineLayout handle

  • renderPass must be a valid VkRenderPass handle

  • = stageCount must be greater t= han 0

  • Each of basePipelineHandle, layout, and renderPass that are valid handles must have bee= n created, allocated, or retrieved from the same VkDevice

Possible values of the flags member of VkGraphicsPipelineCreateInfo and VkComputePipelineCreateInfo, specifying how a pipeline is created, are:

typedef enum VkPipelineCreateFl=
agBits {
    VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT =3D 0x0=
0000001,
    VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT =3D 0x0000=
0002,
    VK_PIPELINE_CREATE_DERIVATIVE_BIT =3D 0x00000004,
    VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT =3D 0x00000008,
    VK_PIPELINE_CREATE_DISPATCH_BASE =3D 0x00000010,
    VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR =3D VK_PIPELINE=
_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT,
    VK_PIPELINE_CREATE_DISPATCH_BASE_KHR =3D VK_PIPELINE_CREATE_DISPATCH_BA=
SE,
} VkPipelineCreateFlagBits;
  • VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT specifies that = the created pipeline will not be optimized. Using this flag may reduce the time taken= to create the pipeline.

  • VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT specifies that the pipeline to be created is allowed to be the parent of a pipeline that will be created in a subsequent call to vkCreate= GraphicsPipelines or vkCreateComputePipelines.

  • VK_PIPELINE_CREATE_DERIVATIVE_BIT specifies that the pipeli= ne to be created will be a child of a previously created parent pipeline.

  • VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT specifi= es that any shader input variables decorated as ViewIndex will be assi= gned values as if they were decorated as DeviceIndex.

  • VK_PIPELINE_CREATE_DISPATCH_BASE specifies that a compute p= ipeline can be used with vkCmd= DispatchBase with a non-zero base workgroup.

It is valid to set both VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT and VK_PIPELINE_CREATE_DERIVATIVE_BIT. This allows a pipeline to be both a parent and possibly a child in a pipeline hierarchy. See Pipeline Derivatives for more information.

typedef VkFlags VkPipelineCreateFlags;

VkPipelineCreateFlags is a bitmask type for setting a mask = of zero or more VkPipelineCreateFlagBits.

The VkPipelineDynamicStateCreateInfo structure is defined a= s:

typedef struct VkPipelineDynami=
cStateCreateInfo {
    VkStructureType                      sType;
    const void*                          pNext;
    VkPipelineDynamicStateCreateFlags    flags;
    uint32_t                             dynamicStateCount;
    const VkDynamicState*                p=
DynamicStates;
} VkPipelineDynamicStateCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • dynamicStateCount is the number of elements in the pDynamicStates array.

  • pDynamicStates is an array of VkDynamicStat= e values specifying which pieces of pipeline state will use the values from dynamic state commands rather than from pipeline state creation info.

Valid Usage (Implicit)
  • s= Type must be VK_STRUCTURE_TY= PE_PIPELINE_DYNAMIC_STATE_CREATE_INFO

  • p= Next must be NULL

  • <= code>flags must be 0<= /p>

  • pDynamicStates must be= a valid pointer to an array of dynamicStateCount valid VkDynamicState values

  • dynamicStateCount must be greater than 0

typedef VkFlags VkPipelineDynamicStateCreateFlags;

VkPipelineDynamicStateCreateFlags is a bitmask type for set= ting a mask, but is currently reserved for future use.

The source of different pieces of dynamic state is specified by the VkPipelineDynamicStateCreateInfo::pDynamicStates property of the currently active pipeline, each of whose elements = must be one of the values:

typedef enum VkDynamicState {
    VK_DYNAMIC_STATE_VIEWPORT =3D 0,
    VK_DYNAMIC_STATE_SCISSOR =3D 1,
    VK_DYNAMIC_STATE_LINE_WIDTH =3D 2,
    VK_DYNAMIC_STATE_DEPTH_BIAS =3D 3,
    VK_DYNAMIC_STATE_BLEND_CONSTANTS =3D 4,
    VK_DYNAMIC_STATE_DEPTH_BOUNDS =3D 5,
    VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK =3D 6,
    VK_DYNAMIC_STATE_STENCIL_WRITE_MASK =3D 7,
    VK_DYNAMIC_STATE_STENCIL_REFERENCE =3D 8=
,
    VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV =3D 1000=
087000,
    VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT =3D 1000=
099000,
    VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT =3D 10001=
43000,
} VkDynamicState;
  • VK_DYNAMIC_STATE_VIEWPORT specifies that the pViewpor= ts state in VkPipelineViewportStateCreateInfo will be ignored and must be set dynamically with vkCmdSetViewport before any draw commands. The number of viewports used by a pipeline is still specified by the viewportCount member of VkPipelineViewportStateCreateInf= o.

  • VK_DYNAMIC_STATE_SCISSOR specifies that the pScissors= state in VkPipelineViewportStateCreateInfo will be ignored and must be set dynamically with vkCmdSetScissor before any draw c= ommands. The number of scissor rectangles used by a pipeline is still specified by the scissorCount member of VkPipelineViewportStateCreateInfo.

  • VK_DYNAMIC_STATE_LINE_WIDTH specifies that the lineWi= dth state in VkPipelineRasterizationStateCreateInfo will be ignore= d and must be set dynamically with vkCmdSetLineWidth before any draw commands that generate line primitives for the rasterizer.

  • VK_DYNAMIC_STATE_DEPTH_BIAS specifies that the depthBiasConstantFactor, depthBiasClamp and depthBiasSlopeFactor states in VkPipelineRasterizationStateCreateInfo will be ignored and must be set dynamically with vkCmdSetDepthBias before any= draws are performed with depthBiasEnable in VkPipelineRasterizationStateCreateInfo set to VK_TRUE.

  • VK_DYNAMIC_STATE_BLEND_CONSTANTS specifies that the blendConstants state in VkPipelineColorBlendStateCreateI= nfo will be ignored and must be set dynamical= ly with vkCmdSetBlendConstants before any draws are per= formed with a pipeline state with VkPipelineColorBlendAttachmentState member blendEnable set to VK_TRUE and any of the blend f= unctions using a constant blend color.

  • VK_DYNAMIC_STATE_DEPTH_BOUNDS specifies that the minDepthBounds and maxDepthBounds states of VkPipelineDepthStencilStateCreateInf= o will be ignored and must be set dynamically with vkCmdSetDepthBounds before an= y draws are performed with a pipeline state with VkPipelineDepthStencilStateCreateInfo member depthBoundsTestEnable set to VK_TRUE.

  • VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK specifies that the compareMask state in VkPipelineDepthStencilStateCreateIn= fo for both front and back will be ignored and must be set dynamically with vkCmdSetStencilCompareMask= before any draws are performed with a pipeline state with VkPipelineDepthStencilStateCreateInfo member stencilTestEnable set to VK_TRUE

  • VK_DYNAMIC_STATE_STENCIL_WRITE_MASK specifies that the writeMask state in VkPipelineDepthStencilStateCreateInfo= for both front and back will be ignored and must be set dynamically with vkCmdSetStencilWriteMask bef= ore any draws are performed with a pipeline state with VkPipelineDepthStencilStateCreateInfo member stencilTestEnable set to VK_TRUE

  • VK_DYNAMIC_STATE_STENCIL_REFERENCE specifies that the reference state in VkPipelineDepthStencilStateCreateInfo= for both front and back will be ignored and must be set dynamically with vkCmdSetStencilReference bef= ore any draws are performed with a pipeline state with VkPipelineDepthStencilStateCreateInfo member stencilTestEnable set to VK_TRUE

  • VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV specifies that the pViewportScalings state in VkPipelineViewportWScalingStateCreateInfoNV will be ignored an= d must be set dynamically with vkCmdSetViewportWScalingNV before any draws are performed with a pipeline state with VkPipelineViewportWScalingStateCreateInfo member viewportScalingEnable set to VK_TRUE

  • VK_DYNAMIC_STATE_DISCARD_RECTANGLES_EXT specifies that the pDiscardRectangles state in VkPipelineDiscardRectangleSta= teCreateInfoEXT will be ignored and must be set dynamically with vkCmdSetDiscardRectangleEXT before any draw or clear commands. The VkDiscardRectangleModeEXT and the number= of active discard rectangles is still specified by the discardRectangleMode and discardRectangleCount members of VkPipelineDiscardRectangleStateCreateInfoEXT.

  • VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT specifies that the sampleLocationsInfo state in VkPipelineSampleLocationsState= CreateInfoEXT will be ignored and must be set dynamically with vkCmdSetSampleLocationsEXT before any draw or clear commands. Enabling custom sample locations is still indicated by the sampleLocationsEnable member of VkPipelineSampleLocationsStateCreateInfoEXT.

9.2.1. Vali= d Combinations of Stages for Graphics Pipelines

If tessellation shader stages are omitted, the tessellation shading and fixed-function stages of the pipeline are skipped.

If a geometry shader is omitted, the geometry shading stage is skipped.<= /p>

If a fragment shader is omitted, the results of fragment processing are undefined. Specifically, any fragment color outputs are considered to have undefined values, and the fragment depth is considered to be unmodified. This can be useful for depth-only renderi= ng.

Presence of a shader stage in a pipeline is indicated by including a val= id VkPipelineShaderStageCreateInfo with module and <= code>pName selecting an entry point from a shader module, where that entry point is valid for the stage specified by stage.

Presence of some of the fixed-function stages in the pipeline is implici= tly derived from enabled shaders and provided state. For example, the fixed-function tessellator is always present when the pipeline has valid Tessellation Control and Tessellation Evaluation shaders= .

For example:

9.3. Pipeline destruction

To destroy a graphics or compute pipeline, call:

void vkDestroyPipeline(
    VkDevice                                    device,
    VkPipeline                                  pipeline,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the pipeline.

  • pipeline is the handle of the pipeline to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to pipeline must have completed execution

  • If VkAllocationCallbacks were provided when pipeline was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when pipeline<= /code> was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice = handle

  • If pipeli= ne is not VK_NULL_HANDLE, pipeline = must be a valid VkPipeline h= andle

  • If pAll= ocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocatio= nCallbacks structure

  • If pipeline<= /code> is a valid handle, it must have be= en created, allocated, or retrieved from device

Host Synchronization
  • Host access to pipeline must be externally synchronized

9.4. Multiple Pipeline Creation

Multiple pipelines can be created simu= ltaneously by passing an array of VkGraphicsPipelineCreateInfo or VkComputePipelineCreateI= nfo structures into the vkCreateGraphicsPipelines and vkCreateComputePipelines commands, respective= ly. Applications can group together similar p= ipelines to be created in a single call, and implementations are encouraged to look for reuse opportunities within a group-create.

When an application attempts to create many pipelines in a single comman= d, it is possible that some subset may fail = creation. In that case, the corresponding entries in the pPipelines outp= ut array will be filled with VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to out of memory errors), the vkCreate*Pipelines commands will return an error code. The implementation will attempt to create all pipelines, and only return VK_NULL_HANDLE values for those that actually failed.

9.5. Pipeline Derivatives

A pipeline derivative is a child pipeline created from a parent pipeline= , where the child and parent are expected to have much commonality. The goal of derivative pipelines is that they be cheaper to create using th= e parent as a starting point, and that it be more efficient (on either host o= r device) to switch/bind between children of the same parent.

A derivative pipeline is created by setting the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag in the Vk*PipelineCreateInfo structure. If this is set, then exactly one of basePipelineHandle or basePipelineIndex members of the structure must have a valid handle/index, and specifies the parent pipeline. If basePipelineHandle is used, the parent pipeline must have already been created. If basePipelineIndex is used, then the parent is being created= in the same command. VK_NULL_HANDLE acts as the invalid handle for basePipelineHandle, and -1 is the invalid index for basePipelineIndex. If basePipelineIndex is used, the base pipeline must appear earlier in the array. The base pipeline must have been created = with the VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT flag set.

9.6. Pipeline Cache

Pipeline cache objects allow the result of pipeline construction to be reused between pipelines and between runs of an application. Reuse between pipelines is achieved by passing the same pipeline cache object when creating multiple related pipelines. Reuse across runs of an application is achieved by retrieving pipeline cach= e contents in one run of an application, saving the contents, and using them to preinitialize a pipeline cache on a subsequent run. The contents of the pipeline cache objects are managed by the implementation. Applications can manage the host memory c= onsumed by a pipeline cache object and control the amount of data retrieved from a pipeline cache object.

Pipeline cache objects are represented by VkPipelineCache h= andles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkPipelineCache)

To create pipeline cache objects, call:

VkResult vkCreateP=
ipelineCache(
    VkDevice                                    device,
    const VkPipelineCacheCreateInfo*      =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkPipelineCache*                            pPipelineCache);
  • device is the logical device that creates the pipeline cach= e object.

  • pCreateInfo is a pointer to a Vk= PipelineCacheCreateInfo structure that contains the initial parameters for the pipeline cache object.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pPipelineCache is a pointer to a VkPipelin= eCache handle in which the resulting pipeline cache object is returned.

Note

Applications can track and manage the = total host memory size of a pipeline cache object using the pAllocator. Applications can limit the amount of data= retrieved from a pipeline cache object in vkGetPipelineCacheData. Implementations should not internally lim= it the total number of entries added to a pipeline cache object or the total host memory consumed.

Once created, a pipeline cache can be = passed to the vkCreateGraphicsPipelines and vkCreateComputePipelines commands. If the pipeline cache passed into these commands is not VK_NULL_HANDLE, the implementation will query it for po= ssible reuse opportunities and update it with new content. The use of the pipeline cache object in these commands is internally synchronized, and the same pipeline cache object c= an be used in multiple threads simultaneously.

Note

Implementations should make every effo= rt to limit any critical sections to the actual accesses to the cache, which is expected to be significantly shorter than the duration of the vkCreateGraphicsPipelines and vkCreateComputePipelines commands.

Valid Usage (Implicit)
  • device<= /code> must be a valid VkDevice handle

  • pC= reateInfo must be a valid pointer = to a valid VkPipelineCacheCreateInfo structure

  • If = pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloc= ationCallbacks structure

  • pPipelineCache must be a valid po= inter to a VkPipelineCache handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkPipelineCacheCreateInfo structure is defined as:

typedef struct VkPipelineCacheC=
reateInfo {
    VkStructureType               sType;
    const void*                   pNext;
    VkPipelineCacheCreateFlags    flags;
    size_t                        initialDataSize;
    const void*                   pInitialData;
} VkPipelineCacheCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • initialDataSize is the number of bytes in pInitialDat= a. If initialDataSize is zero, the pipeline cache will initially = be empty.

  • pInitialData is a pointer to previously retrieved pipeline = cache data. If the pipeline cache data is incompatible (as defined below) with the device, the pipeline cache will be initially empty. If initialDataSize is zero, pInitialData is ignor= ed.

Valid Usage
  • If initialDataSize is not 0, it must be equal to the size of pInitialData, as returned by vkGetPipelineCacheData when pInitialData was originally retrieved

  • If initialDataSize is not 0, pInitialData must have been retrieved from a previous call to vkGetPipelineCacheData

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PIPE= LINE_CACHE_CREATE_INFO

  • pNext must be NULL

  • fl= ags must be 0

  • If = initialDataSize is not 0, pInitialData must be a valid pointer to an array of= initialDataSize bytes

typedef VkFlags VkPipelineCacheCreateFlags;

VkPipelineCacheCreateFlags is a bitmask type for setting a = mask, but is currently reserved for future use.

Pipeline cache objects can be merged u= sing the command:

VkResult vkMergePi=
pelineCaches(
    VkDevice                                    device,
    VkPipelineCache                             dstCache,
    uint32_t                                    srcCacheCount,
    const VkPipelineCache*                =
      pSrcCaches);
  • device is the logical device that owns the pipeline cache o= bjects.

  • dstCache is the handle of the pipeline cache to merge resul= ts into.

  • srcCacheCount is the length of the pSrcCaches = array.

  • pSrcCaches is an array of pipeline cache handles, which wil= l be merged into dstCache. The previous contents of dstCache are included after the merge= .

Note

The details of the merge operation are implementation dependent, but implementations should merge the contents= of the specified pipelines and prune duplicate entries.

Valid Usage
  • dstCache must not appear in = the list of source caches

Valid Usage (Implicit)
  • device<= /code> must be a valid VkDevice handle

  • dstCa= che must be a valid VkPipeli= neCache handle

  • pSr= cCaches must be a valid pointer to= an array of srcCacheCount valid VkPipelineCache = handles

  • srcCacheCount must be greater th= an 0

  • dstCache= must have been created, allocated= , or retrieved from device

  • Each element= of pSrcCaches must have bee= n created, allocated, or retrieved from device

Host Synchronization
  • Host access to dstCache must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Data can be retrieved from a pipeline = cache object using the command:

VkResult vkGetPipe=
lineCacheData(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    size_t*                                     pDataSize,
    void*                                 =
      pData);
  • device is the logical device that owns the pipeline cache.<= /p>

  • pipelineCache is the pipeline cache to retrieve data from.<= /p>

  • pDataSize is a pointer to a value related to the amount of = data in the pipeline cache, as described below.

  • pData is either NULL or a pointer to a buffer.=

If pData is NULL, then the maximum size of the= data that can be retrieved from the pipeline cache, in bytes, is returned in pDataSize= . Otherwise, pDataSize must po= int to a variable set by the user to the size of the buffer, in bytes, pointed to by pData, and on retu= rn the variable is overwritten with the amount of data actually written to pData.

If pDataSize is less than the maximum size that can be retrieved by the pipeline cache, at most pDataSize bytes will be written to pData, and vkGetPipelineCacheData will return VK_INCOMPLETE. Any data written to pData is valid and can be provided as the pInitialData member of the VkPipelineCacheCreateInfo structure passed to vkCreatePipelineCache.

Two calls to vkGetPipelineCacheData with the same parameter= s must retrieve the same data unless a command that modifies the contents of the cache is called between them.

Applications can store the data retrie= ved from the pipeline cache, and use these data, possibly in a future run of the application, to populate new pipeline cache objects. The results of pipeline compiles, however, may depend on the vendor ID, device ID, driver version, and other details of the device. To enable applications to detect when previously retrieved data is incompatible with the device, the initial bytes written to pData must be a header consisting of the following members:

Table 12. Layout for pipeline cache header version= VK_PIPELINE_CACHE_HEADER_VERSION_ONE
Offset Size Meaning

0

4

len= gth in bytes of the entire pipeline cache header written as a stream of bytes, with the least significant byte first

4

4

a <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kPipelineCacheHeaderVersion">VkPipelineCacheHeaderVersion value written as a stream of bytes, with the least significant byte first

8

4

a v= endor ID equal to VkPhysicalDeviceProperties::vendorID written as a stream of bytes, with the least significant byte first

12<= /p>

4

a d= evice ID equal to VkPhysicalDeviceProperties::deviceID written as a stream of bytes, with the least significant byte first

16<= /p>

VK_UUID_SIZE

a p= ipeline cache ID equal to VkPhysicalDeviceProperties::pipelineCacheUUID

The first four bytes encode the length of the entire pipeline cache head= er, in bytes. This value includes all fields in the header including the pipeline cache version field and the size of the length field.

The next four bytes encode the pipeline cache version, as described for VkPipelineCacheHeaderVersion. A consumer of the pipeline cache should u= se the cache version to interpret the remainder of the cache header.

If pDataSize is less than what is necessary to store this h= eader, nothing will be written to pData and zero will be written to pDataSize.

Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • pipelineCache must be a valid VkPipelineCache handle

  • pDa= taSize must be a valid pointer to = a size_t value

  • If the value = referenced by pDataSize is not 0, and pData= is not NULL, pData must be a valid pointer to an array of pDataSize b= ytes

  • pi= pelineCache must have been created= , allocated, or retrieved from device

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Possible values of the second group of four bytes in the header returned= by vkGetPipelineCacheData, encoding the pipeline c= ache version, are:

typedef enum VkPipelineCacheHea=
derVersion {
    VK_PIPELINE_CACHE_HEADER_VERSION_ONE =3D 1,
} VkPipelineCacheHeaderVersion;
  • VK_PIPELINE_CACHE_HEADER_VERSION_ONE specifies version one = of the pipeline cache.

To destroy a pipeline cache, call:

void vkDestroyPipelineCache(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the pipeline cac= he object.

  • pipelineCache is the handle of the pipeline cache to destro= y.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • If VkAllocationCallbacks were provided when pipelineCach= e was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when pipelineC= ache was created, pAllocator must= be NULL

Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • If pipelineCache is not VK_NULL_HANDLE, p= ipelineCache must be a valid VkPipelineCache handle

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllo= cationCallbacks structure

  • If pipelineCache is a valid handle, it must have been created, allocated, or retrieved from device=

Host Synchronization
  • Host access to pipelineCache must<= /strong> be externally synchronized

9.7. Specialization Constants=

Specialization constants are a mechanism whereby constants in a SPIR-V module can have their constant value spec= ified at the time the VkPipeline is created. This allows a SPIR-V module to have constants that can be modified while executing an application that uses the Vulkan API.

Note

Specialization constants are useful to allow a compute shader to have it= s local workgroup size changed at runtime by the user, for example.

Each instance of the VkPipelineShaderStageCreateInfo struct= ure contains a parameter pSpecializationInfo, which can be NULL to indicate no specialization constants, or point to a VkSpecializationInfo structure.

The VkSpecializationInfo structure is defined as:

typedef struct VkSpecialization=
Info {
    uint32_t                           mapEntryCount;
    const VkSpecializationMapEntry*    pMa=
pEntries;
    size_t                             dataSize;
    const void*                        pData;
} VkSpecializationInfo;
  • mapEntryCount is the number of entries in the pMapEnt= ries array.

  • pMapEntries is a pointer to an array of VkSpecializationMapEntry which maps constant IDs to offsets in pData.

  • dataSize is the byte size of the pData buffer.=

  • pData contains the actual constant values to specialize wit= h.

pMapEntries points to a structure of type VkSpecializationMapEntry.

Valid Usage
  • The offset member of each element of pMapEntries = must be less than dataSize

  • The size member of each element of pMapEntries must be less than or equal to dataSize minus offset

Valid Usage (Implicit)
  • If = mapEntryCount is not 0, pMapEntries must be a valid pointer to an array of ma= pEntryCount valid VkSpecializationMapEntry structures

  • If dataSi= ze is not 0, pData must be a valid pointer to an array of dataSize byt= es

The VkSpecializationMapEntry structure is defined as:

typedef struct VkSpecialization=
MapEntry {
    uint32_t    constantID;
    uint32_t    offset;
    size_t      size;
} VkSpecializationMapEntry;
  • constantID is the ID of the specialization constant in SPIR= -V.

  • offset is the byte offset of the specialization constant va= lue within the supplied data buffer.

  • size is the byte size of the specialization constant value = within the supplied data buffer.

If a constantID value is not a specialization constant ID u= sed in the shader, that map entry does not affect the behavior of the pipeline.

Valid Usage
  • For a constantID specialization constant declared in a shader, size must match the byte siz= e of the constantID. If the specialization constant is of type boolean, size<= /code> must be the byte size of VkBool32

In human readable SPIR-V:

OpDecorate %x Spe=
cId 13 ; decorate .x component of WorkgroupSize with ID 13
OpDecorate %y SpecId 42 ; decorate .y component of WorkgroupSize with ID 42
OpDecorate %z SpecId 3  ; decorate .z component of WorkgroupSize with ID 3
OpDecorate %wgsize BuiltIn WorkgroupSize ; decorate WorkgroupSize onto cons=
tant
%i32 =3D OpTypeInt 32 0 ; declare an unsigned 32-bit type
%uvec3 =3D OpTypeVector %i32 3 ; declare a 3 element vector type of unsigne=
d 32-bit
%x =3D OpSpecConstant %i32 1 ; declare the .x component of WorkgroupSize
%y =3D OpSpecConstant %i32 1 ; declare the .y component of WorkgroupSize
%z =3D OpSpecConstant %i32 1 ; declare the .z component of WorkgroupSize
%wgsize =3D OpSpecConstantComposite %uvec3 %x %y %z ; declare WorkgroupSize=

From the above we have three specialization constants, one for each of t= he x, y & z elements of the WorkgroupSize vector.

Now to specialize the above via the specialization constants mechanism:<= /p>

const VkSpecializationMapEntry entries[] =3D
{
    {
        13,                             // constantID
        0 * sizeof(uint32_t),           // offset
        sizeof(uint32_t)                // size
    },
    {
        42,                             // constantID
        1 * sizeof(uint32_t),           // offset
        sizeof(uint32_t)                // size
    },
    {
        3,                              // constantID
        2 * sizeof(uint32_t),           // offset
        sizeof(uint32_t)                // size
    }
};

const uint32_t data[] =3D { 16, 8, 4 }; // our workgroup size is 16x8x4

const VkSpecializationInfo info =3D
{
    3,                                  // mapEntryCount
    entries,                            // pMapEntr=
ies
    3 * sizeof(uint32_t),               // dataSize
    data,                               // pData
};

Then when calling vkCreateComputePipelines= , and passing the VkSpecializationInfo we defined as the pSpecializationIn= fo parameter of VkPipelineShaderStageCreateIn= fo, we will create a compute pipeline with the runtime specified local workgroup size.

Another example would be that an application has a SPIR-V module that ha= s some platform-dependent constants they wish to use.

In human readable SPIR-V:

OpDecorate %1 Spe=
cId 0  ; decorate our signed 32-bit integer constant
OpDecorate %2 SpecId 12 ; decorate our 32-bit floating-point constant
%i32 =3D OpTypeInt 32 1   ; declare a signed 32-bit type
%float =3D OpTypeFloat 32 ; declare a 32-bit floating-point type
%1 =3D OpSpecConstant %i32 -1 ; some signed 32-bit integer constant
%2 =3D OpSpecConstant %float 0.5 ; some 32-bit floating-point constant

From the above we have two specialization constants, one is a signed 32-= bit integer and the second is a 32-bit floating-point.

Now to specialize the above via the specialization constants mechanism:<= /p>

struct SpecializationData {
    int32_t data0;
    float data1;
};

const VkSpecializationMapEntry entries[] =
=3D
{
    {
        0,                                  =
  // constantID
        offsetof(SpecializationData, data0),  // of=
fset
        sizeof(SpecializationData::data0)   =
  // size
    },
    {
        12,                                 =
  // constantID
        offsetof(SpecializationData, data1),  // of=
fset
        sizeof(SpecializationData::data1)   =
  // size
    }
};

SpecializationData data;
data.data0 =3D -42;    // set the data for the 32-bit integer
data.data1 =3D 42.0f;  // set the dat=
a for the 32-bit floating-point

const VkSpecializationInfo info =3D
{
    2,                                  // mapEntryCount
    entries,                            // pMapEntr=
ies
    sizeof(data),                       // dataSize
    &data,                              // pDat=
a
};

It is legal for a SPIR-V module with specializations to be compiled into= a pipeline where no specialization info was provided. SPIR-V specialization constants contain default values such that if a specialization is not provided, the default value will be used. In the examples above, it would be valid for an application to only specialize some of the specialization constants within the SPIR-V module, and let the other constants use their default values encoded within the OpSpecConstant declarations.

9.8. Pipeline Binding

Once a pipeline has been created, it can be bound to the command buffer using the command:

void vkCmdBindPipeline(
    VkCommandBuffer                             commandBuffer,
    VkPipelineBindPoint                         pipelineBindPoint,
    VkPipeline                                  pipeline);
  • commandBuffer is the command buffer that the pipeline will = be bound to.

  • pipelineBindPoint is a VkPipelineBindP= oint value specifying whether to bind to the compute or graphics bind point. Binding one does not disturb the other.

  • pipeline is the pipeline to be bound.

Once bound, a pipeline binding affects subsequent graphics or compute commands in the command buffer until a different pipeline is bound to the bind point. The pipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE controls = the behavior of vkCmdDispatch and vkC= mdDispatchIndirect. The pipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS controls= the behavior of all drawing commands. No other commands are affected by the pipeline state.

Valid Usage
  • If pipelineBindPoint is VK_PIPELINE_BIND_POINT_COMPUTE, the VkCommandPool that commandBuffer was allocated fr= om must support compute operations

  • If pipelineBindPoint is VK_PIPELINE_BIND_POINT_GRAPHICS<= /code>, the VkCommandPool that commandBuffer was allocated fr= om must support graphics operations

  • If pipelineBindPoint is VK_PIPELINE_BIND_POINT_COMPUTE, pipeline must be a compute p= ipeline

  • If pipelineBindPoint is VK_PIPELINE_BIND_POINT_GRAPHICS<= /code>, pipeline must be a graphics = pipeline

  • If the variable multisample rate feature is not supported, pipeline is a graphics pipe= line, the current subpass has no attachments, and this is not the first call to this function with a graphics pipeline after transitioning to the current subpass, then the sample count specified by this pipeline must match that set in the previous pipeline

  • If VkPhysicalDeviceSampleLocatio= nsPropertiesEXT::variableSampleLocations is VK_FALSE, and pipeline is a graphics pipeline = created with a VkPipelineSampleLocatio= nsStateCreateInfoEXT structure having its sampleLocationsEnable member set to VK_TRUE but without VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT enabled then the current render pass instance must have be= en begun by specifying a VkRenderPassSampleLocationsBeginIn= foEXT structure whose pPostSubpassSampleLocations member contains an element with a subpassIndex matching the current subpass index and the sampleLocationsInfo member of that element must match the sampleLocationsInfo specified in VkPipelineSampleLocationsState= CreateInfoEXT when the pipeline was created

Valid Usage (Implicit)
  • comm= andBuffer must be a valid Vk= CommandBuffer handle

  • = pipelineBindPoint must be a valid = VkPipelineBindPoint value

  • pipeline<= /code> must be a valid VkPipeline handle

  • comm= andBuffer must be in the recording state

  • The Vk= CommandPool that commandBuffer was allocated from must support graphics, or compute operations

  • Both of command= Buffer, and pipeline must have been created, allocated, or retrieved from the same VkDevic= e

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

Possible values of vkCmdBindPipeline::pipel= ineBindPoint, specifying the bind point of a pipeline object, are:

typedef enum VkPipelineBindPoin=
t {
    VK_PIPELINE_BIND_POINT_GRAPHICS =3D 0,
    VK_PIPELINE_BIND_POINT_COMPUTE =3D 1,
} VkPipelineBindPoint;
  • VK_PIPELINE_BIND_POINT_COMPUTE specifies binding as a compu= te pipeline.

  • VK_PIPELINE_BIND_POINT_GRAPHICS specifies binding as a grap= hics pipeline.

9.9. Dynamic State

When a pipeline object is bound, any pipeline object state that is not specified as dynamic is applied to the command buffer state. Pipeline object state that is specified as dynamic is not applied to the command buffer state at this time. Instead, dynamic state can be modified at= any time and persists for the lifetime of the command buffer, or until modified by another dynamic state setting command or another pipeline bind.

When a pipeline object is bound, the following applies to each state parameter:

  • If the state is not specified as dynamic in the new pipeline object, then that command buffer state is overwritten by the state in the new pipeline object.

  • If the state is specified as dynamic in both the new and the previous pipeline object, then that command buffer state is not disturbed.

  • If the state is specified as dynamic in the new pipeline object but is not specified as dynamic in the previous pipeline object, then that command buffer state becomes undefined. If the state is an array, then the entire array becomes undefined.

  • If the state is an array specified as dynamic in both the new and the previous pipeline object, and the array size is not the same in both pipeline objects, then that command buffer state becomes undefined.

Dynamic state setting commands must no= t be issued for state that is not specified as dynamic in the bound pipeline object.

Dynamic state that does not affect the result of operations can be left undefined.

Note

For example, if blending is disabled by the pipeline object state then t= he dynamic color blend constants do not need to be specified in the command buffer, even if this state is specified as dynamic in the pipeline object.<= /p>

9.10. Pipeline Shader Information

Information about a particular shader that has been compiled as part of = a pipeline object can be extracted by calling:

VkResult vkGetShad=
erInfoAMD(
    VkDevice                                    device,
    VkPipeline                                  pipeline,
    VkShaderStageFlagBits                       shaderStage,
    VkShaderInfoTypeAMD                         infoType,
    size_t*                                     pInfoSize,
    void*                                 =
      pInfo);
  • device is the device that created pipeline.

  • pipeline is the target of the query.

  • shaderStage identifies the particular shader within the pip= eline about which information is being queried.

  • infoType describes what kind of information is being querie= d.

  • pInfoSize is a pointer to a value related to the amount of = data the query returns, as described below.

  • pInfo is either NULL or a pointer to a buffer.

If pInfo is NULL, then the maximum size of the= information that can be retrieved about the shader, in bytes, is returned in pInfoSize. Otherwise, pInfoSize must po= int to a variable set by the user to the size of the buffer, in bytes, pointed to by pInfo, and on retu= rn the variable is overwritten with the amount of data actually written to pInfo.

If pInfoSize is less than the maximum size that can be retrieved by the pipeline cache, then at most pInfoSize bytes will be writt= en to pInfo, and vkGetShaderInfoAMD will return V= K_INCOMPLETE.

Not all information is available for every shader and implementations ma= y not support all kinds of information for any shader. When a certain type of information is unavailable, the function returns VK_ERROR_FEATURE_NOT_PRESENT.

If information is successfully and fully queried, the function will retu= rn VK_SUCCESS.

For VK_SHADER_INFO_TYPE_STATISTICS_AMD, an instance of VkShaderStatisticsInfoAMD will be written to the buffer pointe= d to by pInfo. This structure will be populated with statistics regarding the physical device resources used by that shader along with other miscellaneous information and is described in further detail below.

For VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, pInfo= points to a UTF-8 null-terminated string containing human-readable disassembly. The exact formatting and contents of the disassembly string are vendor-specific.

The formatting and contents of all other types of information, including VK_SHADER_INFO_TYPE_BINARY_AMD, are left to the vendor and are= not further specified by this extension.

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • pipeline= must be a valid VkPipeline<= /code> handle

  • shade= rStage must be a valid VkShaderStageFlagBits value

  • infoType= must be a valid VkShaderInfoTypeAMD value

  • pInfoSi= ze must be a valid pointer to a size_t value

  • If the value refe= renced by pInfoSize is not 0, and pInfo is not NULL, pInfo m= ust be a valid pointer to an array of pInfoSize bytes=

  • pipeline must have been created, allocated, o= r retrieved from device

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_FEATURE_NOT_PRESENT

  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkShaderStatisticsInfoAMD structure is defined as:

typedef struct VkShaderStatisti=
csInfoAMD {
    VkShaderStageFlags          shaderStageMask;
    VkShaderResourceUsageAMD    resourceUsage;
    uint32_t                    numPhysicalVgprs;
    uint32_t                    numPhysicalSgprs;
    uint32_t                    numAvailableVgprs;
    uint32_t                    numAvailableSgprs;
    uint32_t                    computeWorkGroupSize[3];
} VkShaderStatisticsInfoAMD;
  • shaderStageMask are the combination of logical shader stage= s contained within this shader.

  • resourceUsage is an instance of V= kShaderResourceUsageAMD describing internal physical device resources used by this shader.

  • numPhysicalVgprs is the maximum number of vector instructio= n general-purpose registers (VGPRs) available to the physical device.

  • numPhysicalSgprs is the maximum number of scalar instructio= n general-purpose registers (SGPRs) available to the physical device.

  • numAvailableVgprs is the maximum limit of VGPRs made availa= ble to the shader compiler.

  • numAvailableSgprs is the maximum limit of SGPRs made availa= ble to the shader compiler.

  • computeWorkGroupSize is the local workgroup size of this sh= ader in { X, Y, Z } dimensions.

Some implementations may merge multiple logical shader stages together i= n a single shader. In such cases, shaderStageMask will contain a bitmask of all o= f the stages that are active within that shader. Consequently, if specifying those stages as input to vkGetShaderInfoAMD, the same output information may be returned for all such shader stage queries.

The number of available VGPRs and SGPRs (numAvailableVgprs = and numAvailableSgprs respectively) are the shader-addressable sub= set of physical registers that is given as a limit to the compiler for register assignment. These values may further be limited by im= plementations due to performance optimizations where register pressure is a bottleneck.

The VkShaderResourceUsageAMD structure is defined as:

typedef struct VkShaderResource=
UsageAMD {
    uint32_t    numUsedVgprs;
    uint32_t    numUsedSgprs;
    uint32_t    ldsSizePerLocalWorkGroup;
    size_t      ldsUsageSizeInBytes;
    size_t      scratchMemUsageInBytes;
} VkShaderResourceUsageAMD;
  • numUsedVgprs is the number of vector instruction general-pu= rpose registers used by this shader.

  • numUsedSgprs is the number of scalar instruction general-pu= rpose registers used by this shader.

  • ldsSizePerLocalWorkGroup is the maximum local data store si= ze per work group in bytes.

  • ldsUsageSizeInBytes is the LDS usage size in bytes per work= group by this shader.

  • scratchMemUsageInBytes is the scratch memory usage in bytes= by this shader.

10. Memory Allocation

Vulkan memory is broken up into two categories, host memory and= device memory.

10.1. Host Memory

Host memory is memory needed by the Vulkan implementation for non-device-visible storage.

Note

This memory may be used to store the i= mplementation=E2=80=99s representation and state of Vulkan objects.

Vulkan provides applications the opportunity to perform host memory allocations on behalf of the Vulkan implementation. If this feature is not used, the implementation will perform its own memory allocations. Since most memory allocations are off the critical path, this is not meant as a performance feature. Rather, this can be useful for certain em= bedded systems, for debugging purposes (e.g. putting a guard page after all host allocations), or for memory allocation logging.

Allocators are provided by the application as a pointer to a VkAllocationCallbacks structure:

typedef struct VkAllocationCall=
backs {
    void*                                 =
  pUserData;
    PFN_vkAllocationFunction                pfnAllocation;
    PFN_vkReallocationFunction              pfnReallocation;
    PFN_vkFreeFunction                      pfnFree;
    PFN_vkInternalAllocationNotification    pfnInternalAllocation;
    PFN_vkInternalFreeNotification          pfnInternalFree;
} VkAllocationCallbacks;
Valid Usage
  • pfnAllocation must be a vali= d pointer to a valid user-defined PFN_vkAllocationFunction

  • pfnReallocation must be a va= lid pointer to a valid user-defined PFN_vkReallocationFunction

  • pfnFree must be a valid poin= ter to a valid user-defined PFN_vkFreeFunction

  • If either of pfnInternalAllocation or pfnInternalFree is not NULL, both must be valid cal= lbacks

The type of pfnAllocation is:

typedef void* (VKAPI_PTR *PFN=
_vkAllocationFunction)(
    void*                                 =
      pUserData,
    size_t                                      size,
    size_t                                      alignment,
    VkSystemAllocationScope                     allocationScope);
  • pUserData is the value specified for VkAllocationCallbacks::pUserData in= the allocator specified by the application.

  • size is the size in bytes of the requested allocation.

  • alignment is the requested alignment of the allocation in b= ytes and must be a power of two.

  • allocationScope is a VkSystemAlloc= ationScope value specifying the allocation scope of the lifetime of the allocation, as described here.

If pfnAllocation is unable to allocate the requested memory= , it must return NULL. If the allocation was successful, it must= return a valid pointer to memory allocation containing at least size bytes, and with the pointe= r value being a multiple of alignment.

Note

Correct Vulkan operation cannot be ass= umed if the application does not follow these rules.

For example, pfnAllocation (or pfnReallocation= ) could cause termination of running Vulkan instance(s) on a failed allocation for debugging purposes, either directly or indirectly. In these circumstances, it cannot be assu= med that any part of any affected VkInstance objects are going to operate correctly (even vkDestroyInstance), and the application must ensure it cleans up properly via other means (e.g. process termination).

If pfnAllocation returns NULL, and if the impl= ementation is unable to continue correct processing of the current command without the requested allocation, it must treat this as a run-t= ime error, and generate VK_ERROR_OUT_OF_HOST_MEMORY at the appropriate time for the co= mmand in which the condition was detected, as described in = Return Codes.

If the implementation is able to continue correct processing of the curr= ent command without the requested allocation, then it = may do so, and must not generate VK_ERROR_OUT_OF_HOST_MEMORY as a result of this faile= d allocation.

The type of pfnReallocation is:

typedef void* (VKAPI_PTR *PFN=
_vkReallocationFunction)(
    void*                                 =
      pUserData,
    void*                                 =
      pOriginal,
    size_t                                      size,
    size_t                                      alignment,
    VkSystemAllocationScope                     allocationScope);
  • pUserData is the value specified for VkAllocationCallbacks::pUserData in= the allocator specified by the application.

  • pOriginal must be either = NULL or a pointer previously returned by pfnReallocation or pfnAllocation of the same a= llocator.

  • size is the size in bytes of the requested allocation.

  • alignment is the requested alignment of the allocation in b= ytes and must be a power of two.

  • allocationScope is a VkSystemAlloc= ationScope value specifying the allocation scope of the lifetime of the allocation, as described here.

pfnReallocation must retu= rn an allocation with enough space for size bytes, and the contents of the original allocation from b= ytes zero to min(original size, new size) - 1 must be preserved in the returned allocation. If size is larger than the old size, the contents of the addit= ional space are undefined. If satisfying these requirements involves creating a new allocation, then the old allocation should be freed.

If pOriginal is NULL, then pfnReallocati= on must behave equivalently to a call to PFN_vkAllocationFunctio= n with the same parameter values (without pOriginal).

If size is zero, then pfnReallocation must behave equivalently to a call to PFN_vkFreeFunction with the same pUserData parameter value, and pMemory equal to pOriginal.<= /p>

If pOriginal is non-NULL, the implementation <= strong class=3D"purple">must ensure that alignment is equal to the alignment used to origi= nally allocate pOriginal.

If this function fails and pOriginal is non-NULL the application must not free the old allocation.

pfnReallocation must foll= ow the same rules for return values as PFN_vkAllocationFunction.

The type of pfnFree is:

typedef void (VKAPI_PTR *PFN_=
vkFreeFunction)(
    void*                                 =
      pUserData,
    void*                                 =
      pMemory);
  • pUserData is the value specified for VkAllocationCallbacks::pUserData in= the allocator specified by the application.

  • pMemory is the allocation to be freed.

pMemory may be NULL= , which the callback must handle s= afely. If pMemory is non-NULL, it must be a pointer previously allocated by pfnAllocation or pfnReallocation. The application should free this memory.<= /p>

The type of pfnInternalAllocation is:

typedef void (VKAPI_PTR *PFN_=
vkInternalAllocationNotification)(
    void*                                 =
      pUserData,
    size_t                                      size,
    VkInternalAllocationType                    allocationType,
    VkSystemAllocationScope                     allocationScope);
  • pUserData is the value specified for VkAllocationCallbacks::pUserData in= the allocator specified by the application.

  • size is the requested size of an allocation.

  • allocationType is a VkInternalAll= ocationType value specifying the requested type of an allocation.

  • allocationScope is a VkSystemAlloc= ationScope value specifying the allocation scope of the lifetime of the allocation, as described here.

This is a purely informational callback.

The type of pfnInternalFree is:

typedef void (VKAPI_PTR *PFN_=
vkInternalFreeNotification)(
    void*                                 =
      pUserData,
    size_t                                      size,
    VkInternalAllocationType                    allocationType,
    VkSystemAllocationScope                     allocationScope);
  • pUserData is the value specified for VkAllocationCallbacks::pUserData in= the allocator specified by the application.

  • size is the requested size of an allocation.

  • allocationType is a VkInternalAll= ocationType value specifying the requested type of an allocation.

  • allocationScope is a VkSystemAlloc= ationScope value specifying the allocation scope of the lifetime of the allocation, as described here.

Each allocation has an allocation scope which defines its lifet= ime and which object it is associated with. Possible values passed to the allocationScope parameter of the callback functions specified by VkAllocationCallback= s, indicating the allocation scope, are:

typedef enum VkSystemAllocation=
Scope {
    VK_SYSTEM_ALLOCATION_SCOPE_COMMAND =3D 0=
,
    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT =3D 1,
    VK_SYSTEM_ALLOCATION_SCOPE_CACHE =3D 2,
    VK_SYSTEM_ALLOCATION_SCOPE_DEVICE =3D 3,
    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE =3D 4,
} VkSystemAllocationScope;
  • VK_SYSTEM_ALLOCATION_SCOPE_COMMAND specifies that the alloc= ation is scoped to the duration of the Vulkan command.

  • VK_SYSTEM_ALLOCATION_SCOPE_OBJECT specifies that the alloca= tion is scoped to the lifetime of the Vulkan object that is being created or used.

  • VK_SYSTEM_ALLOCATION_SCOPE_CACHE specifies that the allocat= ion is scoped to the lifetime of a VkPipelineCache or VkValidationCacheEXT object.

  • VK_SYSTEM_ALLOCATION_SCOPE_DEVICE specifies that the alloca= tion is scoped to the lifetime of the Vulkan device.

  • VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE specifies that the allo= cation is scoped to the lifetime of the Vulkan instance.

Most Vulkan commands operate on a single object, or there is a sole obje= ct that is being created or manipulated. When an allocation uses an allocation scope of VK_SYSTEM_ALLOCATION_SCOPE_OBJECT or VK_SYSTEM_ALLOCATION_SCOPE_CACHE, the allocation is scoped to = the object being created or manipulated.

When an implementation requires host memory, it will make callbacks to t= he application using the most specific allocator and allocation scope available:

  • If an allocation is scoped to the duration of a command, the allocator will use the VK_SYSTEM_ALLOCATION_SCOPE_COMMAND allocation sco= pe. The most specific allocator available is used: if the object being created or manipulated has an allocator, that object=E2=80=99s allocator wi= ll be used, else if the parent VkDevice has an allocator it will be used, else if the parent VkInstance has an allocator it will b= e used. Else,

  • If an allocation is associated with an object of type VkValidationCacheEXT or VkPipelineCache, the allocator will use the VK_SYSTEM_ALLOCATION_SCOPE_CACHE allocation scope. The most specific allocator available is used (cache, else device, else instance). Else,

  • If an allocation is scoped to the lifetime of an object, that object is being created or manipulated by the command, and that object=E2=80=99s type= is not VkDevice or VkInstance, the allocator will us= e an allocation scope of VK_SYSTEM_ALLOCATION_SCOPE_OBJECT. The most specific allocator available is used (object, else device, else instance). Else,

  • If an allocation is scoped to the lifetime of a device, the allocator will use an allocation scope of VK_SYSTEM_ALLOCATION_SCOPE_DEVICE. The most specific allocator available is used (device, else instance). Else,

  • If the allocation is scoped to the lifetime of an instance and the instance has an allocator, its allocator will be used with an allocation scope of VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE.

  • Otherwise an implementation will allocate memory through an alternative mechanism that is unspecified.

Objects that are allocated from pools do not specify their own allocator= . When an implementation requires host memory for such an object, that memory is sourced from the object=E2=80=99s parent pool=E2=80=99s allocator.

The application is not expected to handle allocating memory that is inte= nded for execution by the host due to the complexities of differing security implementations across multiple platforms. The implementation will allocate such memory internally and invoke an application provided informational callback when these internal allocations are allocated and freed. Upon allocation of executable memory, pfnInternalAllocation wi= ll be called. Upon freeing executable memory, pfnInternalFree will be called= . An implementation will only call an informational callback for executable memory allocations and frees.

The allocationType parameter to the pfnInternalAlloca= tion and pfnInternalFree functions may be one of the following values:

typedef enum VkInternalAllocati=
onType {
    VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE =3D 0,
} VkInternalAllocationType;
  • VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE specifies that the allocation is intended for execution by the host.

An implementation must only make calls= into an application-provided allocator during the execution of an API command. An implementation must only make calls in= to an application-provided allocator from the same thread that called the provoking API command. The implementation should not synchronize= calls to any of the callbacks. If synchronization is needed, the callbacks must provide it themselves. The informational callbacks are subject to the same restrictions as the allocation callbacks.

If an implementation intends to make calls through an VkAllocationCallbacks structure between the time a vkCre= ate* command returns and the time a corresponding vkDestroy* comman= d begins, that implementation must save a c= opy of the allocator before the vkCreate* command returns. The callback functions and any data structures they rely upon must remain valid for the lifetime of the object they are associated with.

If an allocator is provided to a vkCreate* command, a c= ompatible allocator must be provided to the corresp= onding vkDestroy* command. Two VkAllocationCallbacks structures are compatible if memory allocated with pfnAllocation or pfnReallocation i= n each can be freed with pfnReallocation or pfnFree in the othe= r. An allocator must not be provided to a vkDestroy* command if an allocator was not provided to the corresponding vkCreate* comm= and.

If a non-NULL allocator is used, the pfnAllocation, pfnReallocation and pfnFree members must be non-NULL and point to valid implementations of the callbacks. An application can choose to not provide = informational callbacks by setting both pfnInternalAllocation and pfnInternalFree to= NULL. pfnInternalAllocation and pfnInternalFree must either both be NULL or both be non-NULL.

If pfnAllocation or pfnReallocation fail, the = implementation may fail object creation and/or generate = an VK_ERROR_OUT_OF_HOST_MEMORY error, as appropriate.

Allocation callbacks must not call any= Vulkan commands.

The following sets of rules define when an implementation is permitted t= o call the allocator callbacks.

pfnAllocation or pfnReallocation may be called in the following situations:

  • Allocations scoped to a VkDevice or VkInstance= may be allocated from any API command.

  • Allocations scoped to a command may be= allocated from any API command.

  • Allocations scoped to a VkPipelineCache may only be allocated from:

    • vkCreatePipelineCache

    • vkMergePipelineCaches for dstCache

    • vkCreateGraphicsPipelines for pipelineCache

    • vkCreateComputePipelines for pipelineCache

  • Allocations scoped to a VkValidationCacheEXT may only be allocated from:

    • vkCreateValidationCacheEXT

    • vkMergeValidationCachesEXT for dstCache

    • vkCreateShaderModule for validationCache in VkShaderModuleValidationCacheCreateInfoEXT

  • Allocations scoped to a VkDescriptorPool may only be allocated from:

    • any command that takes the pool as a direct argument

    • vkAllocateDescriptorSets for the descriptorPool member of its pAllocateInfo parameter

    • vkCreateDescriptorPool

  • Allocations scoped to a VkCommandPool may only be allocated from:

    • any command that takes the pool as a direct argument

    • vkCreateCommandPool

    • vkAllocateCommandBuffers for the commandPool m= ember of its pAllocateInfo parameter

    • any vkCmd* command whose commandBuffer was all= ocated from that VkCommandPool

  • Allocations scoped to any other object may only be allocated in that object=E2=80=99s vkCreate* command.

pfnFree may be called in = the following situations:

  • Allocations scoped to a VkDevice or VkInstance= may be freed from any API command.

  • Allocations scoped to a command must b= e freed by any API command which allocates such memory.

  • Allocations scoped to a VkPipelineCache may be freed from vkDestroyPipelineCache.

  • Allocations scoped to a VkValidationCacheEXT may be freed from vkDestroyValidationCacheEXT.

  • Allocations scoped to a VkDescriptorPool may be freed from

    • any command that takes the pool as a direct argument

  • Allocations scoped to a VkCommandPool may be freed from:

    • any command that takes the pool as a direct argument

    • vkResetCommandBuffer whose commandBuffer was a= llocated from that VkCommandPool

  • Allocations scoped to any other object may be freed in that object=E2=80=99s vkDestroy* command.

  • Any command that allocates host memory may also free host memory of the same scope.

10.2. Device Memory

Device memory is memory that is visible to the device=E2=80=89= =E2=80=94=E2=80=89for example the contents of the image or buffer objects, which can= be natively used by the device.

Memory properties of a physical device describe the memory heaps and mem= ory types available.

To query memory properties, call:

void vkGetPhysicalDeviceMemoryProperties(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceMemoryProperties*           pMemoryProperties);<=
/pre>
  • physicalDevice is the handle to the device to query.

  • pMemoryProperties points to an instance of VkPhysicalDeviceMemoryProperties structure in which the proper= ties are returned.

Valid Usage (Implicit)
  • physicalDevice must= be a valid VkPhysicalDevice handle

  • pMemoryProperties must be a valid pointer to a VkPhysicalDeviceMemoryProperties structure

The VkPhysicalDeviceMemoryProperties structure is defined a= s:

typedef struct VkPhysicalDevice=
MemoryProperties {
    uint32_t        memoryTypeCount;
    VkMemoryType    memoryTypes[VK_MAX_MEMORY_TYPES];
    uint32_t        memoryHeapCount;
    VkMemoryHeap    memoryHeaps[VK_MAX_MEMORY_HEAPS];
} VkPhysicalDeviceMemoryProperties;
  • memoryTypeCount is the number of valid elements in the memoryTypes array.

  • memoryTypes is an array of VkMemoryType s= tructures describing the memory types that can be used to access memory allocated from the heaps specified by memoryHeaps.

  • memoryHeapCount is the number of valid elements in the memoryHeaps array.

  • memoryHeaps is an array of VkMemoryHeap s= tructures describing the memory heaps from which memory can be allocated.

The VkPhysicalDeviceMemoryProperties structure describes a = number of memory heaps as well as a number of memory types that can be used to access memory allocated in those heaps. Each heap describes a memory resource of a particular size, and each memory type describes a set of memory properties (e.g. host cached vs uncached) that can be used with a given memory heap= . Allocations using a particular memory type will consume resources from the heap indicated by that memory type=E2=80=99s heap index. More than one memory type may share each = heap, and the heaps and memory types provide a mechanism to advertise an accurate size of the physical memory resources while allowing the memory to be used with a variety of different properties.

The number of memory heaps is given by memoryHeapCount and = is less than or equal to VK_MAX_MEMORY_HEAPS. Each heap is described by an element of the memoryHeaps array = as a VkMemoryHeap structure. The number of memory types available across all memory heaps is given by memoryTypeCount and is less than or equal to VK_MAX_MEMORY_TYPES. Each memory type is described by an element of the memoryTypes= array as a VkMemoryType structure.

At least one heap must include V= K_MEMORY_HEAP_DEVICE_LOCAL_BIT in VkMemoryHeap::flags. If there are multiple heaps that all have similar performance characteristics, they may all include VK_MEMORY_HEAP_DEVICE_LOCAL_BIT. In a unified memory architecture (UMA) system there is often only a single memory heap which is considered to be equally =E2=80=9Clocal=E2=80=9D to th= e host and to the device, and such an implementation must advertise the heap as device-local.

Each memory type returned by vkGetP= hysicalDeviceMemoryProperties must have its propertyFlags set to one of the following values:

  • 0

  • VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT

  • VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
    VK_MEMORY_PROPERTY_HOST_CACHED_BIT

  • VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
    VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT

  • VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT

  • VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT

  • VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
    VK_MEMORY_PROPERTY_HOST_CACHED_BIT

  • VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
    VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT

  • VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
    VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT

  • VK_MEMORY_PROPERTY_PROTECTED_BIT

  • VK_MEMORY_PROPERTY_PROTECTED_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT

There must be at least one memory type= with both the VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bits set in its propertyFlags. There must be at least one memory type wi= th the VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit set in its propertyFlags.

For each pair of elements X and Y retu= rned in memoryTypes, X must be placed at a lower index position = than Y if:

  • either the set of bit flags returned in the propertyFlags m= ember of X is a strict subset of the set of bit flags returned i= n the propertyFlags member of Y.

  • or the propertyFlags members of X and Y are equal, and X belongs to a memory heap with greater performance (as determined in an implementation-specific manner).

Note

There is no ordering requirement between X and = Y elements for the case their propertyFlags members are not in a subset relation. That potentially allows more than one possible way to order the same set of memory types. Notice that the list of all allowed memory property flag combinations is written in the required order. But if instead VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT was before VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, the list would still be = in the required order.

This ordering requirement enables applications to use a simple search lo= op to select the desired memory type along the lines of:

// Find a memory in `memoryTypeBitsRequirement` that includes all of =
`requiredProperties`
int32_t findProperties(const VkPhysicalDev=
iceMemoryProperties* pMemoryProperties,
                       uint32_t memoryTypeBitsRequirement,
                       VkMemoryPropertyFlags requiredProperties) {
    const uint32_t memoryCount =3D pMemory=
Properties->memoryTypeCount;
    for (uint32_t memoryIndex =3D 0; memoryIndex < memoryCount; ++memoryIndex) {
        const uint32_t memoryTypeBits =3D =
(1 << memoryIndex);
        const bool isRequiredMemoryType =3D memoryTypeBitsRequirement & me=
moryTypeBits;

        const VkMemoryPropertyFlags proper=
ties =3D
            pMemoryProperties->memoryTypes[memoryIndex].propertyFlags;
        const bool hasRequiredProperties =3D
            (properties & requiredProperties) =3D=3D requiredProperties=
;

        if (isRequiredMemoryType && =
hasRequiredProperties)
            return s=
tatic_cast<int32_t>(memoryIndex);
    }

    // failed to find memory type
    return -1=
;
}

// Try to find an optimal memory type, or if it doe=
s not exist try fallback memory type
// `device` is the VkDevice
// `image` is the VkImage that requires memory to b=
e bound
// `memoryProperties` properties as returned by vkG=
etPhysicalDeviceMemoryProperties
// `requiredProperties` are the property flags that=
 must be present
// `optimalProperties` are the property flags that =
are preferred by the application
VkMemoryRequirements memoryRequirements;
vkGetImageMemoryRequirements(device, image, &memoryRequirements);
int32_t memoryType =3D
    findProperties(&memoryProperties, memoryRequirements.memoryTypeBits=
, optimalProperties);
if (memoryType =3D=3D -1) // not found; try fallback properties<=
/span>
    memoryType =3D
        findProperties(&memoryProperties, memoryRequirements.memoryType=
Bits, requiredProperties);

To query memory properties, call:

void vkGetPhysicalDeviceMemoryProperties2(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceMemoryProperties2*          pMemoryProperties);<=
/pre>

or the equivalent command

void vkGetPhysicalDeviceMemoryProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceMemoryProperties2*          pMemoryProperties);<=
/pre>
  • physicalDevice is the handle to the device to query.

  • pMemoryProperties points to an instance of VkPhysicalDeviceMemoryProperties2 structure in which the properties are returned.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pMemoryProperties must be a valid pointer to a VkPhysicalDeviceMemoryProperties2 structure

The VkPhysicalDeviceMemoryProperties2 structure is defined = as:

typedef struct VkPhysicalDevice=
MemoryProperties2 {
    VkStructureType                     sType;
    void*                               pN=
ext;
    VkPhysicalDeviceMemoryProperties    memoryProperties;
} VkPhysicalDeviceMemoryProperties2;

or the equivalent

typedef VkPhysicalDeviceMemoryProperties2 VkPhysicalDeviceMemo=
ryProperties2KHR;
Valid Usage (Implicit)
  • = sType must be VK_STRUCTURE_T= YPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2

  • = pNext must be NULL

The VkMemoryHeap structure is defined as:

typedef struct VkMemoryHeap {
    VkDeviceSize         size;
    VkMemoryHeapFlags    flags;
} VkMemoryHeap;
  • size is the total memory size in bytes in the heap.

  • flags is a bitmask of VkMemoryHeapFla= gBits specifying attribute flags for the heap.

Bits which may be set in VkMemoryHeap::flags, indicating attribute flags for the heap, are:

typedef enum VkMemoryHeapFlagBi=
ts {
    VK_MEMORY_HEAP_DEVICE_LOCAL_BIT =3D 0x00000001,
    VK_MEMORY_HEAP_MULTI_INSTANCE_BIT =3D 0x00000002,
    VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR =3D VK_MEMORY_HEAP_MULTI_INSTANCE=
_BIT,
} VkMemoryHeapFlagBits;
  • VK_MEMORY_HEAP_DEVICE_LOCAL_BIT specifies that the heap corresponds to device local memory. Device local memory may have different pe= rformance characteristics than host local memory, and may support differ= ent memory property flags.

  • VK_MEMORY_HEAP_MULTI_INSTANCE_BIT specifies that in a logic= al device representing more than one physical device, there is a per-physical device instance of the heap memory. By default, an allocation from such a heap will be replicated to each physical device=E2=80=99s instance of the heap.

typedef VkFlags VkMemoryHeapFlags;

VkMemoryHeapFlags is a bitmask type for setting a mask of z= ero or more VkMemoryHeapFlagBits.

The VkMemoryType structure is defined as:

typedef struct VkMemoryType {
    VkMemoryPropertyFlags    propertyFlags;
    uint32_t                 heapIndex;
} VkMemoryType;

Bits which may be set in VkMemoryType::propertyFlags, indicating properties of a memory heap, are:

typedef enum VkMemoryPropertyFl=
agBits {
    VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT =3D 0x00000001<=
/span>,
    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT =3D 0x00000002<=
/span>,
    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT =3D 0x00000004=
,
    VK_MEMORY_PROPERTY_HOST_CACHED_BIT =3D 0x00000008,
    VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT =3D 0x00000=
010,
    VK_MEMORY_PROPERTY_PROTECTED_BIT =3D 0x00000020,
} VkMemoryPropertyFlagBits;
  • VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit specifies that memo= ry allocated with this type is the most efficient for device access. This property will be set if and only if the memory type belongs to a heap with the VK_MEMORY_HEAP_DEVICE_LOCAL_BIT set.

  • VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit specifies that memo= ry allocated with this type can be mapped fo= r host access using vkMapMemory.

  • VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit specifies that the= host cache management commands vkFlushMappedMemoryRan= ges and vkInvalidateMappedMemoryRanges are not = needed to flush host writes to the device or make device writes visible to the host, respectively.

  • VK_MEMORY_PROPERTY_HOST_CACHED_BIT bit specifies that memor= y allocated with this type is cached on the host. Host memory accesses to uncached memory are slower than to cached memory, however uncached memory is always host coherent.

  • VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit specifies that = the memory type only allows device access to the memory. Memory types must not have both VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT and VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set. Additionally, the object=E2=80=99s backing memory = may be provided by the implementation lazily as specified in Lazily= Allocated Memory.

  • VK_MEMORY_PROPERTY_PROTECTED_BIT bit specifies that the mem= ory type only allows device access to the memory, and allows protected queue operations to access the memory. Memory types must not have VK_MEMOR= Y_PROPERTY_PROTECTED_BIT set and any of VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set, or VK_MEMORY_PROPERTY_HOST_COHERENT_BIT set, or VK_MEMORY_PROPERTY_HOST_CACHED_BIT set.

typedef VkFlags VkMemoryPropertyFlags;

VkMemoryPropertyFlags is a bitmask type for setting a mask = of zero or more VkMemoryPropertyFlagBits.

A Vulkan device operates on data in device memory via memory objects tha= t are represented in the API by a VkDeviceMemory handle:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDeviceMemory)

To allocate memory objects, call:

VkResult vkAllocat=
eMemory(
    VkDevice                                    device,
    const VkMemoryAllocateInfo*           =
      pAllocateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDeviceMemory*                             pMemory);

Allocations returned by vkAllocateMemory are guaranteed to = meet any alignment requirement of the implementation. For example, if an implementation requires 128 byte alignment for images an= d 64 byte alignment for buffers, the device memory returned through this mechanism would be 128-byte aligned. This ensures that applications can correc= tly suballocate objects of different types (with potentially different alignment requirements) in the same memory object.

When memory is allocated, its contents are undefined with the following constraint:

  • The contents of unprotected memory must not be a function of data protected memory objects, even if those memory objects were previously freed.

Note

The contents of memory allocated by one application should not be a function of data from protected memory objects of another application, even if those memory objects were previously freed.

The maximum number of valid memory allocations that can exist simultaneously within a VkDevice may= be restricted by implementation- or platform-dependent limits. If a call to vkAllocateMemory would cause the total n= umber of allocations to exceed these limits, such a call will fail and must return VK_ERROR_TOO_MANY_OBJECTS. The maxMemoryAllocationCount feature describes the number of allocations that c= an exist simultaneously before encountering these internal limits.

Some platforms may have a limit on the= maximum size of a single allocation. For example, certain systems may fail to = create allocations with a size greater than or equal to 4GB. Such a limit is implementation-dependent, and if such a failure occurs then the error VK_ERROR_OUT_OF_DEVICE_MEMORY must be returned. This limit is advertised in VkPhysicalDeviceMaintenance3Propert= ies::maxMemoryAllocationSize.

Valid Usage
Valid Usage (Implicit)
  • device must be a valid VkDevice h= andle

  • pAllo= cateInfo must be a valid pointer t= o a valid VkMemoryAllocateInfo structure

  • If pAllo= cator is not NULL, pAllocator must be a valid pointer to a valid VkAllocation= Callbacks structure

  • pMemory must be a valid pointer to a Vk= DeviceMemory handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_INVALID_EXTERNAL_HANDLE

The VkMemoryAllocateInfo structure is defined as:

typedef struct VkMemoryAllocate=
Info {
    VkStructureType    sType;
    const void*        pNext;
    VkDeviceSize       allocationSize;
    uint32_t           memoryTypeIndex;
} VkMemoryAllocateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • allocationSize is the size of the allocation in bytes

  • memoryTypeIndex is an index identifying a memory type from = the memoryTypes array of the VkP= hysicalDeviceMemoryProperties structure

An instance of the VkMemoryAllocateInfo struct= ure defines a memory import operation if the pNext chain contains an instance of on= e of the following structures:

Importing memory must not modify the c= ontent of the memory. Implementations must ensure that importin= g memory does not enable the importing Vulkan instance to access any memory or resources in other Vulkan instances other than that corresponding to the memory object imported. Implementations must also ensure accessin= g imported memory which has not been initialized does not allow the importing Vulkan instance to obtain dat= a from the exporting Vulkan instance or vice-versa.

Note

How exported and imported memory is isolated is left to the implementati= on, but applications should be aware that such isolation may prevent implementations from placing multiple exportable memory objects in the same physical or virtual page. Hence, applications should avoid creating= many small external memory objects whenever possible.

When performing a memory import operation, it is the responsibility of t= he application to ensure the external handles meet all valid usage requirements. However, implementations must perform suf= ficient validation of external handles to ensure that the operation results in a valid memory object which will not cause program termination, device loss, queue stalls, or corruptio= n of other resources when used as allowed according to its allocation parameters. If the external handle provided does not meet these requirements, the implementation must fail the memory impor= t operation with the error code VK_ERROR_INVALID_EXTERNAL_HANDLE.

Valid Usage
  • If the pNext chain contains an instance of VkExportMemoryAllocateInfo, and any of the handle types sp= ecified in VkExportMemoryAllocateInfo::handleTypes re= quire a dedicated allocation, as reported by vkGetPhysicalDeviceImageForm= atProperties2 in VkExternalImageFormatProperties::externalMemoryPrope= rties::externalMemoryFeatures or VkExternalBufferProperties::externalMemoryProperties= ::externalMemoryFeatures, the pNext chain must contain an instance of VkMemoryDedicatedAllocateInfo or VkDedicatedAllocationMemoryAlloc= ateInfoNV with either its image or buffer field set to = a value other than VK_NULL_HANDLE.

  • If the pNext chain contains an instance of VkExportMemoryAllocateInfo, it must not contain an instance of VkExportMemoryAllocateInfoNV or VkExportMemoryWin32HandleInfoNV.

  • If the pNext chain contains an instance of VkImportMemoryWin32HandleInfoKHR, it = must not contain an instance of VkImportMemoryWin32HandleInfoNV.

  • If the parameters define an import operation, the external handle specified was created by the Vulkan API, and the external handle type is VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR, then the val= ues of allocationSize and memoryTypeIndex must match those specified when the memory object being imported was created.

  • If the parameters define an import operation and the external handle specified was created by the Vulkan API, the device mask specified by VkMemoryAllocateFlagsInfo must match that specified when the memory object being imported was allocated.

  • If the parameters define an import operation and the external handle specified was created by the Vulkan API, the list of physical devices that comprise the logical device passed to vkAllocateMemo= ry must match the list of physical devices that comprise the logical device on which the memory was originally allocated.

  • If the parameters define an import operation and the external handle is an NT handle or a global share handle created outside of the Vulkan API, the value of memoryTypeIndex must be one of those returned by vkGetMemoryWin32HandlePropertiesKHR.

  • If the parameters define an import operation, the external handle was created by the Vulkan API, and the external handle type is VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR or VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR, then = the values of allocationSize and memoryTypeIndex must match those specified when the memory object being imported was created.

  • If the parameters define an import operation and the external handle type is VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT, or VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT, allocationSize must match th= e size reported in the memory requirements of the image or buffer member of the= instance of VkDedicatedAllocationMemoryAllocateInfoNV included in the pNext chain.

  • If the parameters define an import operation and the external handle type is VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT, allocationSize must match th= e size specified when creating the Direct3D 12 heap from which the external handle was extracted.

  • If the parameters define an import operation and the external handle is a POSIX file descriptor created outside of the Vulkan API, the value of memoryTypeIndex must be one = of those returned by vkGetMemoryFdPropertiesKHR.

  • If the protected memory feature is not enabled, the VkMemoryAllocateInfo::memoryTypeIndex must not indicate a memory type that reports VK_MEMORY_PROPERTY_PROTECTED_BIT.

  • If the parameters define an import operation and the external handle is a host pointer, the value of memoryTypeIndex must be one of those returned by vkGetMemoryHostPointerProp= ertiesEXT

  • If the parameters define an import operation and the external handle is a host pointer, allocationSize must be an integer multiple of VkPhysicalDeviceExternalMemoryHostPropertiesEXT::minImpo= rtedHostPointerAlignment

  • If the parameters define an import operation and the external handle type is VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BIT_ANDROID:

  • If the parameters do not define an import operation, and the pNext chain contains an instance of VkExportMemoryAllocateInfo with VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID included in its handleTypes member, and the pNext= contains an instance of VkMemoryDedicatedAllocateInfo= with image not equal to VK_NULL_HANDLE, then allocationSize must be 0, otherwise allocationSize must be greater than 0.

  • If the parameters define an import operation, the external handle is an Android hardware buffer, and the pNext chain includes an insta= nce of VkMemoryDedicatedAllocateInfo with image that is not VK_NULL_HANDLE:

    • The Android hardware buffer=E2=80=99s usage mus= t include at least one of AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT or AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE

    • The format of image must = be VK_FORMAT_UNDEFINED or the format returned by vkGetAndroi= dHardwareBufferPropertiesANDROID in VkAndroidHardwareBufferF= ormatPropertiesANDROID::format for the Android hardware buffer.

    • The width, height, and array layer dimensions of image and = the Android hardware buffer must be identical=

    • If the Android hardware buffer=E2=80=99s usage includes AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE, the image must have =E2=8C=8Alog2(max(width, height))=E2=8C=8B +=20 1 mip levels, otherwise it must ha= ve exactly 1 mip level.

    • Each bit set in the usage of image must be listed in AHardwareBuffer Usage Equivalence, and if there is a corresponding AHARDWAREBUFFER_USAGE bit listed that bit must be included in the Android hardware buffer=E2=80=99s usage

Valid Usage (Implicit)

If the pNext chain includes a VkMemoryDedicatedAlloca= teInfo structure, then that structure includes a handle of the sole buffer or imag= e resource that the memory can be bound to.=

The VkMemoryDedicatedAllocateInfo structure is defined as:<= /p>

typedef struct VkMemoryDedicate=
dAllocateInfo {
    VkStructureType    sType;
    const void*        pNext;
    VkImage            image;
    VkBuffer           buffer;
} VkMemoryDedicatedAllocateInfo;

or the equivalent

typedef VkMemoryDedicatedAllocateInfo VkMemoryDedicatedAllocat=
eInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • image is VK_NULL_HANDLE or a handle of = an image which this memory will be bound to.

  • buffer is VK_NULL_HANDLE or a handle of= a buffer which this memory will be bound to.

Valid Usage
  • At least one of image and buffer must be VK_NULL_HANDLE

  • If image is not VK_NULL_HANDLE, VkMemoryAllocateInfo::allocationSize must equal the VkMemoryRequirements::size of the image

  • If image is not VK_NULL_HANDLE, imag= e must have been created without VK_IMAGE_CREATE_SPARSE_BINDING_BIT set in VkImageCreateInfo::flags

  • If buffer is not VK_NULL_HANDLE, VkMemoryAllocateInfo::allocationSize must equal the VkMemoryRequirements::size of the buffer

  • If buffer is not VK_NULL_HANDLE, buf= fer must have been created without VK_BUFFER_CREATE_SPARSE_BINDING_BIT set i= n VkBufferCreateInfo::flags

  • If image is not VK_NULL_HANDLE and VkMemoryAllocateInfo defines a memory import oper= ation with handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT, or VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT, and the external handle was created by the Vulkan API, then the memory being imported must also be a dedicated image a= llocation and image must be identical to the image associated with the imported memory.

  • If buffer is not VK_NULL_HANDLE and VkMemoryAllocateInfo defines a memory import oper= ation with handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT, or VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT, and the external handle was created by the Vulkan API, then the memory being imported must also be a dedicated buffer = allocation and buffer must be identical to the buffer associated with the imported memory.

  • If image is not VK_NULL_HANDLE and VkMemoryAllocateInfo defines a memory import oper= ation with handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, the memory being imported must also be a dedicated i= mage allocation and image must be identical to the image associated with the impor= ted memory.

  • If buffer is not VK_NULL_HANDLE and VkMemoryAllocateInfo defines a memory import oper= ation with handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, the memory being imported must also be a dedicated b= uffer allocation and buffer must be identical to the buffer associated with the imported memory.

  • If image is not VK_NULL_HANDLE, imag= e must not have been created with VK_IMAGE_CREATE_DISJOINT_BIT set in VkImageCreateInfo::flags

Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= MEMORY_DEDICATED_ALLOCATE_INFO

  • If image is not VK_NULL_HANDLE, image must be a valid VkImage h= andle

  • If buffer is not VK_NULL_HANDLE, buffer must be a valid VkBuffer handle

  • Both of <= code>buffer, and image that are valid handles must have been created, allocated, or retrieved fr= om the same VkDevice

If the pNext chain includes a VkDedicatedAllocationMemoryAllocateInfoNV structure, then that structure includes a handle of the sole buffer or image resource that the memory can be bound to.

The VkDedicatedAllocationMemoryAllocateInfoNV structure is = defined as:

typedef struct VkDedicatedAlloc=
ationMemoryAllocateInfoNV {
    VkStructureType    sType;
    const void*        pNext;
    VkImage            image;
    VkBuffer           buffer;
} VkDedicatedAllocationMemoryAllocateInfoNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • image is VK_NULL_HANDLE or a handle of = an image which this memory will be bound to.

  • buffer is VK_NULL_HANDLE or a handle of= a buffer which this memory will be bound to.

Valid Usage

The VkExportMemoryAllocateInfo structure= is defined as:

typedef struct VkExportMemoryAl=
locateInfo {
    VkStructureType                    sType;
    const void*                        pNext;
    VkExternalMemoryHandleTypeFlags    handleTypes;
} VkExportMemoryAllocateInfo;

or the equivalent

typedef VkExportMemoryAllocateInfo VkExportMemoryAllocateInfoK=
HR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleTypes is a bitmask of VkExternalMemoryHandleTypeFlagBits = specifying one or more memory handle types the application can export f= rom the resulting allocation. The application can request multiple hand= le types for the same allocation.

Valid Usage
Valid Usage (Implicit)

To specify additional attributes of NT handles exported from a memory object, add the VkExportMemoryWin32Handle= InfoKHR structure to the pNext chain of the VkMemoryAllocateInfo<= /a> structure. The VkExportMemoryWin32HandleInfoKHR structure is defined as:<= /p>

typedef struct VkExportMemoryWi=
n32HandleInfoKHR {
    VkStructureType               sType;
    const void*                   pNext;
    const SECURITY_ATTRIBUTES*    pAttribu=
tes;
    DWORD                         dwAccess;
    LPCWSTR                       name;
} VkExportMemoryWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • pAttributes is a pointer to a Windows SECURITY_ATTRIB= UTES structure specifying security attributes of the handle.

  • dwAccess is a DWORD specifying access rights o= f the handle.

  • name is a NULL-terminated UTF-16 string to associate with t= he underlying resource referenced by NT handles exported from the created memory.

If this structure is not present, or if pAttributes is set = to NULL, default security descriptor values will be used, and child processes create= d by the application will not inherit the handle, as described in the MSDN documentation for =E2=80=9CSynchronization Object Security and Access Right= s=E2=80=9D1. Further, if the structure is not present, the access rights will be

DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRIT= E

for handles of the following types:

VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT

And

GENERIC_ALL

for handles of the following types:

VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT

Valid Usage
  • If VkExportMemoryAllocateInfo::handle= Types does not include VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT, or VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT, VkExportMemoryWin32HandleInfoKHR must= not be in the pNext chain of VkMemoryAllocateInfo.

Valid Usage (Implicit)

The VkImportMemoryWin32HandleInfoKHR structure is defined a= s:

typedef struct VkImportMemoryWi=
n32HandleInfoKHR {
    VkStructureType                       sType;
    const void*                           pNext;
    VkExternalMemoryHandleTypeFlagBits    handleType;
    HANDLE                                handle;
    LPCWSTR                               name;
} VkImportMemoryWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleType specifies the type of handle or name.

  • handle is the external handle to import, or NULL.

  • name is a NULL-terminated UTF-16 string naming the underlyi= ng memory resource to import, or NULL.

Importing memory objects from Windows handles does not transfer ownershi= p of the handle to the Vulkan implementation. For handle types defined as NT handles, the application must release ownership using the CloseHandle system call when the handle is= no longer needed.

Applications can import the same under= lying memory into multiple instances of Vulkan, into the same instance from which it was exported, and multiple times into a given Vulkan instance. In all cases, each import operation must = create a distinct VkDeviceMemory object.

Valid Usage
  • If handleType is not 0, it must be supported for import, as reported by VkExternalImageFormatPropertie= s or VkExternalBufferProperties.

  • The memory from which handle was exported, or the memory named= by name must have been created = on the same underlying physical device as device.

  • If handleType is not 0, it must be defined as an NT handle or a global share handle.

  • If handleType is not VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT, or VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT, name<= /code> must be NULL.

  • If handleType is not 0 and handle is= NULL, name must name a valid memory resource of the = type specified by handleType.

  • If handleType is not 0 and name is <= code>NULL, handle must be a valid handle of the type specif= ied by handleType.

  • if handle is not NULL, name must be = NULL.

  • If handle is not NULL, it must obey any requirements listed for handleType in external memory handle types compatibility.

  • If name is not NULL, it = must obey any requirements listed for handleType in external memory handle types compatibility.

Valid Usage (Implicit)

To export a Windows handle representing the underlying resources of a Vu= lkan device memory object, call:

VkResult vkGetMemo=
ryWin32HandleKHR(
    VkDevice                                    device,
    const VkMemoryGetWin32HandleInfoKHR*  =
      pGetWin32HandleInfo,
    HANDLE*                                     pHandle);
  • device is the logical device that created the device memory= being exported.

  • pGetWin32HandleInfo is a pointer to an instance of the VkMemoryGetWin32HandleInfoKHR structure = containing parameters of the export operation.

  • pHandle will return the Windows handle representing the und= erlying resources of the device memory object.

For handle types defined as NT handles, the handles returned by vkGetMemoryWin32HandleKHR are owned by the application. To avoid leaking resources, the application must release ownership of them using the CloseHandle system call when they are no longer need= ed.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkMemoryGetWin32HandleInfoKHR structure is defined as:<= /p>

typedef struct VkMemoryGetWin32=
HandleInfoKHR {
    VkStructureType                       sType;
    const void*                           pNext;
    VkDeviceMemory                        memory;
    VkExternalMemoryHandleTypeFlagBits    handleType;
} VkMemoryGetWin32HandleInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memory is the memory object from which the handle will be exported.

  • handleType is the type of handle requested.

Valid Usage
  • handleType must have been in= cluded in VkExportMemoryAllocateInfo::handleTyp= es when memory was created.

  • If handleType is defined as an NT handle, vkGetMemoryWin32HandleKHR must be called no more than once for each valid unique combination of memory and handleType.

  • handleType must be defined a= s an NT handle or a global share handle.

Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= MEMORY_GET_WIN32_HANDLE_INFO_KHR

  • pNex= t must be NULL

  • memory must be a valid VkDe= viceMemory handle

  • <= code>handleType must be a valid VkExternalMemoryHandleTypeFlagBits va= lue

Windows memory handles compatible with Vulkan m= ay also be created by non-Vulkan APIs using methods beyond the scope of this specification. To determine the correct parameters to use when importing such handles, call:

VkResult vkGetMemo=
ryWin32HandlePropertiesKHR(
    VkDevice                                    device,
    VkExternalMemoryHandleTypeFlagBits          handleType,
    HANDLE                                      handle,
    VkMemoryWin32HandlePropertiesKHR*           pMemoryWin32HandlePropertie=
s);
  • device is the logical device that will be importing h= andle.

  • handleType is the type of the handle handle.

  • handle is the handle which will be imported.

  • pMemoryWin32HandleProperties will return properties of handle.

Valid Usage
  • handle must be an external m= emory handle created outside of the Vulkan API.

  • handleType must not be one o= f the handle types defined as opaque.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_INVALID_EXTERNAL_HANDLE

The VkMemoryWin32HandlePropertiesKHR structure returned is = defined as:

typedef struct VkMemoryWin32Han=
dlePropertiesKHR {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           memoryTypeBits;
} VkMemoryWin32HandlePropertiesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memoryTypeBits is a bitmask containing one bit set for ever= y memory type which the specified windows handle can= be imported as.

To import memory from a POSIX file descriptor handle, add a VkImportMemoryFdInfoKHR structure to the pNext chain of the VkMemoryAllocateInfo structure. The VkImportMemoryFdInfoKHR structure is defined as:

typedef struct VkImportMemoryFd=
InfoKHR {
    VkStructureType                       sType;
    const void*                           pNext;
    VkExternalMemoryHandleTypeFlagBits    handleType;
    int                             =
      fd;
} VkImportMemoryFdInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleType specifies the handle type of fd.

  • fd is the external handle to import.

Importing memory from a file descriptor transfers ownership of the file descriptor from the application to the Vulkan implementation. The application must not perform any oper= ations on the file descriptor after a successful import.

Applications can import the same under= lying memory into multiple instances of Vulkan, into the same instance from which it was exported, and multiple times into a given Vulkan instance. In all cases, each import operation must = create a distinct VkDeviceMemory object.

Valid Usage
Valid Usage (Implicit)

To export a POSIX file descriptor representing the underlying resources = of a Vulkan device memory object, call:

VkResult vkGetMemo=
ryFdKHR(
    VkDevice                                    device,
    const VkMemoryGetFdInfoKHR*           =
      pGetFdInfo,
    int*                            =
            pFd);
  • device is the logical device that created the device memory= being exported.

  • pGetFdInfo is a pointer to an instance of the VkMemoryGetFdInfoKHR structure containing paramet= ers of the export operation.

  • pFd will return a file descriptor representing the underlyi= ng resources of the device memory object.

Each call to vkGetMemoryFdKHR must= create a new file descriptor and transfer ownership of it to the application. To avoid leaking resources, the application must release ownership of the file descriptor using the close system call when it is no long= er needed, or by importing a Vulkan memory object from it. Where supported by the operating system, the implementation must set the file descriptor to be closed automatically when an execve syst= em call is made.

Valid Usage (Implicit)
  • device must be a valid VkDevice h= andle

  • pGetFdIn= fo must be a valid pointer to a va= lid VkMemoryGetFdInfoKHR structure

  • pFd must be a valid pointer to a int= value

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkMemoryGetFdInfoKHR structure is defined as:

typedef struct VkMemoryGetFdInf=
oKHR {
    VkStructureType                       sType;
    const void*                           pNext;
    VkDeviceMemory                        memory;
    VkExternalMemoryHandleTypeFlagBits    handleType;
} VkMemoryGetFdInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memory is the memory object from which the handle will be exported.

  • handleType is the type of handle requested.

The properties of the file descriptor exported depend on the value of handleType. See VkExternalMemoryHandleTypeFlagBits<= /a> for a description of the properties of the defined external memory handle types.

Note

The size of the exported file may be l= arger than the size requested by VkMemoryAllocateInfo::allocationSize. If handleType is VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_= BIT_EXT, then the application can query the file= =E2=80=99s actual size with lseek(2).

Valid Usage
  • handleType must have been in= cluded in VkExportMemoryAllocateInfo::handleTyp= es when memory was created.

  • handleType must be defined a= s a POSIX file descriptor handle.

Valid Usage (Implicit)
  • sType = must be VK_STRUCTURE_TYPE_MEMORY_GE= T_FD_INFO_KHR

  • pNext = must be NULL

  • memory must be a valid VkDeviceMemor= y handle

  • hand= leType must be a valid VkExternalMemoryHandleTypeFlagBits value

POSIX file descriptor memory handles compatible with Vulkan may also be created by non-Vulkan APIs using methods beyond the scope of this specification. To determine the correct parameters to use when importing such handles, call:

VkResult vkGetMemo=
ryFdPropertiesKHR(
    VkDevice                                    device,
    VkExternalMemoryHandleTypeFlagBits          handleType,
    int                             =
            fd,
    VkMemoryFdPropertiesKHR*                    pMemoryFdProperties);
  • device is the logical device that will be importing f= d.

  • handleType is the type of the handle fd.

  • fd is the handle which will be imported.

  • pMemoryFdProperties will return properties of the handle fd.

Valid Usage
  • fd must be an external memor= y handle created outside of the Vulkan API.

  • handleType must not be VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR.

Valid Usage (Implicit)
  • de= vice must be a valid VkDevic= e handle

  • handleType must be a valid VkExternalMemoryHandleTypeFlagBits value=

  • = pMemoryFdProperties must be a valid pointer to a VkMemoryFdPropertiesKHR structure

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_INVALID_EXTERNAL_HANDLE

The VkMemoryFdPropertiesKHR structure returned is defined a= s:

typedef struct VkMemoryFdProper=
tiesKHR {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           memoryTypeBits;
} VkMemoryFdPropertiesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memoryTypeBits is a bitmask containing one bit set for ever= y memory type which the specified file descriptor ca= n be imported as.

To import memory from a host pointer, add a VkImportMemoryHostPointerInfoEXT stru= cture to the pNext chain of the VkMemoryAllocateInfo structure. The VkImportMemoryHostPointerInfoEXT structure is defined as:<= /p>

typedef struct VkImportMemoryHo=
stPointerInfoEXT {
    VkStructureType                       sType;
    const void*                           pNext;
    VkExternalMemoryHandleTypeFlagBits    handleType;
    void*                                 =
pHostPointer;
} VkImportMemoryHostPointerInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleType specifies the handle type.

  • pHostPointer is the host pointer to import from.

Importing memory from a host pointer shares ownership of the memory betw= een the host and the Vulkan implementation. The application can continue to access th= e memory through the host pointer but it is the application=E2=80=99s responsibility to synchronize device an= d non-device access to the underlying memory as defined in Host Access to Device Memory Objects.

Applications can import the same under= lying memory into multiple instances of Vulkan and multiple times into a given Vulkan instance. However, implementations may fail to impo= rt the same underlying memory multiple times into a given physical device due to platform constraints.

Importing memory from a particular host pointer may not be possible due to additional platform-specific restrictions beyond the scope of this specification in which case the implementation mus= t fail the memory import operation with the error code VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR.

The application must ensure that the i= mported memory range remains valid and accessible for the lifetime of the imported memory object.

Valid Usage
  • If handleType is not 0, it must be supported for import, as reported in VkExternalMemoryPropertiesKHR

  • If handleType is not 0, it must be VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT or VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT

  • pHostPointer must be a point= er aligned to an integer multiple of VkPhysicalDeviceExternalMemoryHostPropertiesEXT::minImpo= rtedHostPointerAlignment

  • If handleType is VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, pHostPointer must be a point= er to allocationSize number of bytes of host memory, where allocationSize is the member of th= e VkMemoryAllocateInfo structure this structure is chained to

  • If handleType is VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT, pHostPointer must be a point= er to allocationSize number of bytes of host mapped foreign memory, where allocationSize is t= he member of the VkMemoryAllocateInfo structure this structure is chained to

Valid Usage (Implicit)

To determine the correct parameters to use when importing host pointers, call:

VkResult vkGetMemo=
ryHostPointerPropertiesEXT(
    VkDevice                                    device,
    VkExternalMemoryHandleTypeFlagBits          handleType,
    const void*                                 pHostPointer,
    VkMemoryHostPointerPropertiesEXT*           pMemoryHostPointerPropertie=
s);
  • device is the logical device that will be importing pHostPointer.

  • handleType is the type of the handle pHostPointer.

  • pHostPointer is the host pointer to import from.

Valid Usage
Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_INVALID_EXTERNAL_HANDLE

The VkMemoryHostPointerPropertiesEXT structure is defined a= s:

typedef struct VkMemoryHostPoin=
terPropertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           memoryTypeBits;
} VkMemoryHostPointerPropertiesEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memoryTypeBits is a bitmask containing one bit set for ever= y memory type which the specified host pointer can be imported as.

Valid Usage (Implicit)
  • s= Type must be VK_STRUCTURE_TY= PE_MEMORY_HOST_POINTER_PROPERTIES_EXT

  • p= Next must be NULL

To import memory created outside of the current Vulkan instance from an Android hardware buffer, add a VkImportAndroidHardwareBufferInfoANDROID structure to the pNext chain of the VkMemoryAllocateInfo structure. The VkImportAndroidHardwareBufferInfoANDROID structure is defi= ned as:

typedef struct VkImportAndroidH=
ardwareBufferInfoANDROID {
    VkStructureType            sType;
    const void*                pNext;
    struct AHardwareBuffer*    buffer;
} VkImportAndroidHardwareBufferInfoANDROID;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • buffer is the Android hardware buffer to import.

If the vkAllocateMemory command succeeds, the impl= ementation must acquire a reference to the imported hardware buffer, which it must release when the device memory object is freed. If the command fails, the implementation must not retain a reference.

Valid Usage (Implicit)
  • = sType must be VK_STRU= CTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID

  • buffer must be a valid= pointer to a AHardwareBuffer value

To export an Android hardware buffer representing the underlying resourc= es of a Vulkan device memory object, call:

VkResult vkGetMemo=
ryAndroidHardwareBufferANDROID(
    VkDevice                                    device,
    const VkMemoryGetAndroidHardwareBuffer=
InfoANDROID* pInfo,
    struct AHardwareBuffer**                =
    pBuffer);
  • device is the logical device that created the device memory= being exported.

  • pInfo is a pointer to an instance of the VkMemoryGetAndroidHardwareBuff= erInfoANDROID structure containing parameters of the export operation.

  • pBuffer will return an Android hardware buffer representing= the underlying resources of the device memory object.

Each call to vkGetMemoryAndroidHardwareBufferANDROID must return an Android hardware buffer with a new reference acquired in addition to the reference held by the VkDeviceMemory. To avoid leaking resources, the application must release the reference by calling AHardwareBuffer_release when it is no longer needed. When called with the same handle in VkMemoryGetAndroidHardwareBuff= erInfoANDROID::memory, vkGetMemoryAndroidHardwareBufferANDROID must return the same Android hardware buffer object. If the device memory was created by importing an Android hardware buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same Android hardware buffer object.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkMemoryGetAndroidHardwareBufferInfoANDROID structure i= s defined as:

typedef struct VkMemoryGetAndro=
idHardwareBufferInfoANDROID {
    VkStructureType    sType;
    const void*        pNext;
    VkDeviceMemory     memory;
} VkMemoryGetAndroidHardwareBufferInfoANDROID;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memory is the memory object from which the Android hardware= buffer will be exported.

Valid Usage

To determine the memory parameters to use when importing an Android hard= ware buffer, call:

VkResult vkGetAndr=
oidHardwareBufferPropertiesANDROID(
    VkDevice                                    device,
    const struct AHardwareBuffer*               buffer,
    VkAndroidHardwareBufferPropertiesANDROID*   pProperties);
  • device is the logical device that will be importing b= uffer.

  • buffer is the Android hardware buffer which will be importe= d.

  • pProperties will return properties of buffer.<= /p>

Valid Usage
  • = buffer must be a valid Andro= id hardware buffer object with at least one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags.

Valid Usage (Implicit)
  • device must be a va= lid VkDevice handle

  • buffer must be a va= lid pointer to a valid AHardwareBuffer value

  • pProperties must be a valid pointer to a VkAndroidHardwareBufferPropertiesANDROID structure

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR

The VkAndroidHardwareBufferPropertiesANDROID structure retu= rned is defined as:

typedef struct VkAndroidHardwar=
eBufferPropertiesANDROID {
    VkStructureType    sType;
    void*              pNext;
    VkDeviceSize       allocationSize;
    uint32_t           memoryTypeBits;
} VkAndroidHardwareBufferPropertiesANDROID;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • allocationSize is the size of the external memory

  • memoryTypeBits is a bitmask containing one bit set for ever= y memory type which the specified Android hardware buffer can be imported as.

To obtain format properties of an Android hardware buffer, include an instance of VkAndroidHardwareBufferFormatPropertiesANDROID in = the pNext chain of the V= kAndroidHardwareBufferPropertiesANDROID instance passed to vkGetAndroi= dHardwareBufferPropertiesANDROID. This structure is defined as:

typedef struct VkAndroidHardwar=
eBufferFormatPropertiesANDROID {
    VkStructureType                  sType;
    void*                            pNext=
;
    VkFormat                         format;
    uint64_t                         externalFormat;
    VkFormatFeatureFlags             formatFeatures;
    VkComponentMapping               samplerYcbcrConversionComponents;
    VkSamplerYcbcrModelConversion    suggestedYcbcrModel;
    VkSamplerYcbcrRange              suggestedYcbcrRange;
    VkChromaLocation                 suggestedXChromaOffset;
    VkChromaLocation                 suggestedYChromaOffset;
} VkAndroidHardwareBufferFormatPropertiesANDROID;

If the Android hardware buffer has one of the formats listed in the Format Equivalence table, then format must = have the equivalent Vulkan format listed in the table. Otherwise, format may be VK_FORMAT_UNDEFINED, indicating the Android hardware buffer can only be used = with an external format.

The formatFeatures member must include VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, and should include VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT and VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT.

Note

The formatFeatures member only indicates the features avail= able when using an external-format image created from the Android hardware buffer. Images from Android hardware buffers with a format other than VK_FORMAT_UNDEFINED are subject to the format capabilities obt= ained from vkGetPhysicalDeviceFormatPropert= ies2, and vkGetPhysicalDeviceImageFormatPr= operties2 with appropriate parameters. These sets of features are independent of each other, e.g. the external format will support sampler Y=E2=80=99CBCR conversion= even if the non-external format does not, and writing to non-external format images is possible but writing to external format images is not.

Android hardware buffers with the same external format must have the same support for VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCT= ION_FILTER_BIT, and VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTIO= N_EXPLICIT_FORCEABLE_BIT. in formatFeatures. Other format features may differ between = Android hardware buffers that have the same external format. This allows applications to use the same VkSample= rYcbcrConversion object (and samplers and pipelines created from them) for any Android hardware buffers that have the same external format.

If format is not VK_FORMAT_UNDEFINED, then the= value of samplerYcbcrConversionComponents must= be valid when used as the components member of VkSam= plerYcbcrConversionCreateInfo with that format. If format is VK_FORMAT_UNDEFINED, all members of samplerYcbcrConversionComponents must= be VK_COMPONENT_SWIZZLE_IDENTITY.

Implementations may not always be able= to determine the color model, numerical range, or chroma offsets of the image contents, so the values in VkAndroidHardwareBufferFormatPropertiesANDROID are only sugges= tions. Applications should treat these values as= sensible defaults to use in the absence of more reliable information obtained through some other means. If the underlying physical device is also usable via OpenGL ES with the GL_OES_EGL_image_external extension, the implementation should sugg= est values that will produce similar sampled values as would be obtained by sampling the same external image via samplerExternalOES in OpenGL ES using equivalent sam= pler parameters.

Note

Since GL_OES_EGL_image_external does not require the same sampling and conversion calculations as Vulkan does, achieving identical results between APIs may= not be possible on some implementations.

Valid Usage (Implicit)
  • sType must be V= K_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID

The VkExportMemoryAllocateInfoNV struc= ture is defined as:

typedef struct VkExportMemoryAl=
locateInfoNV {
    VkStructureType                      sType;
    const void*                          pNext;
    VkExternalMemoryHandleTypeFlagsNV    handleTypes;
} VkExportMemoryAllocateInfoNV;
Valid Usage (Implicit)

When VkExportMemoryAllocateInfoNV::handleTypes includes VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV, add a VkExportMemoryWin32HandleInfoNV to the pNext chai= n of the VkExportMemoryAllocateInfoNV structure to= specify security attributes and access rights for the memory object=E2=80=99s external handle.

The VkExportMemoryWin32HandleInfoNV structure is defined as= :

typedef struct VkExportMemoryWi=
n32HandleInfoNV {
    VkStructureType               sType;
    const void*                   pNext;
    const SECURITY_ATTRIBUTES*    pAttribu=
tes;
    DWORD                         dwAccess;
} VkExportMemoryWin32HandleInfoNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • pAttributes is a pointer to a Windows SECURITY_ATTRIB= UTES structure specifying security attributes of the handle.

  • dwAccess is a DWORD specifying access rights o= f the handle.

If this structure is not present, or if pAttributes is set = to NULL, default security descriptor values will be used, and child processes create= d by the application will not inherit the handle, as described in the MSDN documentation for =E2=80=9CSynchronization Object Security and Access Right= s=E2=80=9D[1]. Further, if the structure is not present, the access rights will be

DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE
Valid Usage (Implicit)

The VkImportMemoryWin32HandleInfoNV structure is defined as= :

typedef struct VkImportMemoryWi=
n32HandleInfoNV {
    VkStructureType                      sType;
    const void*                          pNext;
    VkExternalMemoryHandleTypeFlagsNV    handleType;
    HANDLE                               handle;
} VkImportMemoryWin32HandleInfoNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleType is 0 or a VkExternalMemoryHandleTypeFlagBitsNV value specifying the type of memory handle in handle.

  • handle is a Windows HANDLE referring to the me= mory.

If handleType is 0, this structure is ignored = by consumers of the VkMemoryAllocateInfo structure it is chained from= .

Valid Usage
  • handleType must not have mor= e than one bit set.

  • handle must be a valid handl= e to memory, obtained as specified by handleType.

Valid Usage (Implicit)

Bits which can be set in handleT= ype are:

Possible values of VkImportMemoryWin32H= andleInfoNV::handleType, specifying the type of an external memory handle, are:

typedef enum VkExternalMemoryHa=
ndleTypeFlagBitsNV {
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV =3D 0x00000001,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV =3D 0x00000002,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV =3D 0x00000004,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV =3D 0x00000008,
} VkExternalMemoryHandleTypeFlagBitsNV;
  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV spec= ifies a handle to memory returned by vkGetMemoryWin32Hand= leNV.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV specifie= s a handle to memory returned by vkGetMemoryWin32Hand= leNV, or one duplicated from such a handle using DuplicateHandle().

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV specifies= a valid NT handle to memory returned by IDXGIResource1::CreateSharedHandle(), or a handle= duplicated from such a handle using DuplicateHandle().

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV speci= fies a handle to memory returned by IDXGIResource::GetSharedHandle().=

editing-note

(Jon) If additional (non-Win32) bits are added to the possible memory ty= pes, this type should move to the VK_N= V_external_memory_capabilities section, and each bit would then be protected by ifdefs for the extension it=E2=80=99s defined by.

typedef VkFlags VkExternalMemoryHandleTypeFlagsNV;

VkExternalMemoryHandleTypeFlagsNV is a bitmask type for set= ting a mask of zero or more VkExternalMemoryHandl= eTypeFlagBitsNV.

To retrieve the handle corresponding to a device memory object created w= ith VkExportMemoryAllocateInfoNV::handl= eTypes set to include VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV or VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV, call:<= /p>

VkResult vkGetMemo=
ryWin32HandleNV(
    VkDevice                                    device,
    VkDeviceMemory                              memory,
    VkExternalMemoryHandleTypeFlagsNV           handleType,
    HANDLE*                                     pHandle);
Valid Usage
Valid Usage (Implicit)
  • devi= ce must be a valid VkDevice<= /code> handle

  • memo= ry must be a valid VkDeviceM= emory handle

  • = handleType must be a valid combina= tion of VkExternalMemoryHandleTypeFla= gBitsNV values

  • = handleType must not be 0

  • pHa= ndle must be a valid pointer to a = HANDLE value

  • memory<= /code> must have been created, allocated,= or retrieved from device

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_OUT_OF_HOST_MEMORY

If the pNext chain of VkMemoryAllocat= eInfo includes a VkMemoryAllocateFlagsInfo structure, then that structure inclu= des flags and a device mask controlling how many instances of the memory will b= e allocated.

The VkMemoryAllocateFlagsInfo structure is defined as:

typedef struct VkMemoryAllocate=
FlagsInfo {
    VkStructureType          sType;
    const void*              pNext;
    VkMemoryAllocateFlags    flags;
    uint32_t                 deviceMask;
} VkMemoryAllocateFlagsInfo;

or the equivalent

typedef VkMemoryAllocateFlagsInfo VkMemoryAllocateFlagsInfoKHR=
;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkMemoryAll= ocateFlagBits controlling the allocation.

  • deviceMask is a mask of physical devices in the logical dev= ice, indicating that memory must be allocated = on each device in the mask, if VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT is set in flags.

If VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT is not set, the numbe= r of instances allocated depends on whether VK_MEMORY_HEAP_MULTI_INSTANCE_BIT is set in the memory heap. If VK_MEMORY_HEAP_MULTI_INSTANCE_BIT is set, then memory is al= located for every physical device in the logical device (as if deviceMask has bits set for all device indices). If VK_MEMORY_HEAP_MULTI_INSTANCE_BIT is not set, then a single instance of memory is allocated (as if deviceMask is set to on= e).

On some implementations, allocations from a multi-instance heap may consume memory on all physical devices even if the deviceMask excludes= some devices. If VkPhysicalDeviceGroupProperties::subsetAllocation is VK_TRUE, then memory is only consumed for the devices in the d= evice mask.

Note

In practice, most allocations on a multi-instance heap will be allocated across all physical devices. Unicast allocation support is an optional optimization for a minority of allocations.

Valid Usage
  • If VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT is set, deviceMask= must be a valid device mask.

  • If VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT is set, deviceMask= must not be zero

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_MEMO= RY_ALLOCATE_FLAGS_INFO

  • flag= s must be a valid combination of <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kMemoryAllocateFlagBits">VkMemoryAllocateFlagBits values

Bits which can be set in VkMemoryAllocateFlagsInfo::flags, controlling device memory allocation, are:

typedef enum VkMemoryAllocateFl=
agBits {
    VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT =3D 0x00000001,
    VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR =3D VK_MEMORY_ALLOCATE_DEVICE_MA=
SK_BIT,
} VkMemoryAllocateFlagBits;

or the equivalent

typedef VkMemoryAllocateFlagBits VkMemoryAllocateFlagBitsKHR;<=
/code>
  • VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT specifies that memory wi= ll be allocated for the devices in VkMemoryAllocateFlagsInfo::deviceMask<= /code>.

typedef VkFlags VkMemoryAllocateFlags;

or the equivalent

typedef VkMemoryAllocateFlags VkMemoryAllocateFlagsKHR;=

VkMemoryAllocateFlags is a bitmask type for setting a mask = of zero or more VkMemoryAllocateFlagBits.

To free a memory object, call:

void vkFreeMemory(
    VkDevice                                    device,
    VkDeviceMemory                              memory,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that owns the memory.

  • memory is the VkDeviceMemory object to = be freed.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Before freeing a memory object, an application = must ensure the memory object is no longer in use by the device=E2=80=94=E2=80=8Bfor example by co= mmand buffers in the pending state. The memory can remain bound to images or = buffers at the time the memory object is freed, but any further use of them (on host or device) for anything other than destroying those objects will result in undefined behavior. If there are still any bound images or buffers, the memory may not be immediately released by the implementation, but mu= st be released by the time all bound images and buffers have been destroyed. Once memory is released, it is returned to the heap from which it was allocated.

How memory objects are bound to Images and Buffers is described in detai= l in the Resource Memory Association section.

If a memory object is mapped at the time it is freed, it is implicitly unmapped.

Note

As described below, host writes = are not implicitly flushed when the memory object is unmapped, but the implementation must guarantee that writes= that have not been flushed do not affect any other memory.

Valid Usage
  • All submitted commands that refer to memory (via images or buffers) must have completed execution

Valid Usage (Implicit)
  • device must be a valid VkDevice handl= e

  • If memory= is not VK_NULL_HANDLE, memory must be a valid VkDeviceMemory handle

  • If pAllocato= r is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCall= backs structure

  • If memory is= a valid handle, it must have been create= d, allocated, or retrieved from device

Host Synchronization
  • Host access to memory must be externally synchronized

10.2.1. Host Access to Device Memory Ob= jects

Memory objects created with vkAllocateMemory are n= ot directly host accessible.

Memory objects created with the memory property VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT are considered mappabl= e. Memory objects must be mappable in order = to be successfully mapped on the host.

To retrieve a host virtual address pointer to a region of a mappable mem= ory object, call:

VkResult vkMapMemo=
ry(
    VkDevice                                    device,
    VkDeviceMemory                              memory,
    VkDeviceSize                                offset,
    VkDeviceSize                                size,
    VkMemoryMapFlags                            flags,
    void**                                =
      ppData);
  • device is the logical device that owns the memory.

  • memory is the VkDeviceMemory object to = be mapped.

  • offset is a zero-based byte offset from the beginning of th= e memory object.

  • size is the size of the memory range to map, or VK_WHOLE_SIZE to map from offset to the end of th= e allocation.

  • flags is reserved for future use.

  • ppData points to a pointer in which is returned a host-acce= ssible pointer to the beginning of the mapped range. This pointer minus offset must be aligned to at least VkPhysicalDeviceLimits::minMemoryMapAlign= ment.

It is an application error to call vkMapMemory on a memory = object that is already mapped.

Note

vkMapMemory will fail if the implementation is unable to al= locate an appropriately sized contiguous virtual address range, e.g. due to virtual address space fragmentation or platform limits. In such cases, vkMapMemory must return VK_ERROR_MEMORY_MAP_FAILED. The application can improve the likelihoo= d of success by reducing the size of the mapped range and/or removing unneeded mappings using VkUnmapMemory.

vkMapMemory does not check whether the device memory is cur= rently in use before returning the host-accessible pointer. The application must guarantee that any p= reviously submitted command that writes to this range has completed before the host reads from or writes to that range, and that any previously submitted command that reads from that range has completed before the host writes to that region (see here for details on fulfilling such a guarantee). If the device memory was allocated without the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT set, these guarantees must be made for an extended range: the application must round down the start of the range to the nearest multiple of VkPhysicalDeviceLimits::nonCoherentAtomSi= ze, and round the end of the range up to the nearest multiple of VkPhysicalDeviceLimits::nonCoherentAtomSi= ze.

While a range of device memory is mapped for host access, the applicatio= n is responsible for synchronizing both device and host access to that memory range.

Note

It is important for the application developer to become meticulously familiar with all of the mechanisms described in the chapter on Synchronization and Cache Control as they are crucial to maintaining memory access ordering.

Valid Usage
  • memory must not be currently= mapped

  • offset must be less than the= size of memory

  • If size is not equal to VK_WHOLE_SIZE, size= must be greater than 0

  • If size is not equal to VK_WHOLE_SIZE, size= must be less than or equal to the size of the memory minus offse= t

  • memory must have been create= d with a memory type that reports VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT

  • memory must not have been al= located with multiple instances.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle=

  • memory must be a valid VkDeviceMemory = handle

  • flags must be 0

  • ppData must be a valid pointer to a pointer value

  • memory must have been created, allocated, or retrieved= from device

Host Synchronization
  • Host access to memory must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_MEMORY_MAP_FAILED

typedef VkFlags VkMemoryMapFlags;

VkMemoryMapFlags is a bitmask type for setting a mask, but = is currently reserved for future use.

Two commands are provided to enable applications to work with non-cohere= nt memory allocations: vkFlushMappedMemoryRanges and vkInvalidateMappedMemoryRanges.

Note

If the memory object was created with the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT set, vkFlushMappedMemoryRanges and vkInvalidateMappedMemoryRa= nges are unnecessary and may have a performance co= st. However, availability and visibility operations still need to be managed on the device. See the description of host access types for more information.

To flush ranges of non-coherent memory from the host caches, call:

VkResult vkFlushMa=
ppedMemoryRanges(
    VkDevice                                    device,
    uint32_t                                    memoryRangeCount,
    const VkMappedMemoryRange*            =
      pMemoryRanges);
  • device is the logical device that owns the memory ranges.

  • memoryRangeCount is the length of the pMemoryRanges array.

  • pMemoryRanges is a pointer to an array of VkMappedMemoryRange structures describing the memo= ry ranges to flush.

vkFlushMappedMemoryRanges guarantees that host writes to th= e memory ranges described by pMemoryRanges can= be made available to device access, via availabilit= y operations from the VK_ACCESS_HOST_WRITE_BIT access type.

Within each range described by pMemoryRanges, each set of nonCoherentAtomSize bytes in that range is flushed if any byte= in that set has been written by the host since it was first mapped, or the last tim= e it was flushed. If pMemoryRanges includes sets of nonCoherentAtomSize bytes where no bytes have been written by the host, those bytes must not be flushed.

Unmapping non-coherent memory does not implicitly flush the mapped memor= y, and host writes that have not been flushed may not ever be visible to the device. However, implementations must ensure that= writes that have not been flushed do not become visible to any other memory.

Note

The above guarantee avoids a potential memory corruption in scenarios wh= ere host writes to a mapped memory object have not been flushed before the memory is unmapped (or freed), and the virtual address range is subsequentl= y reused for a different mapping (or memory allocation).

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

To invalidate ranges of non-coherent memory from the host caches, call:<= /p>

VkResult vkInvalid=
ateMappedMemoryRanges(
    VkDevice                                    device,
    uint32_t                                    memoryRangeCount,
    const VkMappedMemoryRange*            =
      pMemoryRanges);
  • device is the logical device that owns the memory ranges.

  • memoryRangeCount is the length of the pMemoryRanges array.

  • pMemoryRanges is a pointer to an array of VkMappedMemoryRange structures describing the memo= ry ranges to invalidate.

vkInvalidateMappedMemoryRanges guarantees that device write= s to the memory ranges described by pMemoryRanges, which have been made= visible to the VK_ACCESS_HOST_WRITE_BIT and VK_ACCESS_HOST_READ_= BIT access types, are made visible to the host. If a range of non-coherent memory is written by the host and then invalidated without first being flushed, its contents are undefined.

Within each range described by pMemoryRanges, each set of nonCoherentAtomSize bytes in that range is invalidated if any = byte in that set has been written by the device since it was first mapped, or the last time it was invalidated.

Note

Mapping non-coherent memory does not implicitly invalidate the mapped memory, and device writes that have not been invalidated must be made visible before the host reads or overwrites them.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkMappedMemoryRange structure is defined as:

typedef struct VkMappedMemoryRa=
nge {
    VkStructureType    sType;
    const void*        pNext;
    VkDeviceMemory     memory;
    VkDeviceSize       offset;
    VkDeviceSize       size;
} VkMappedMemoryRange;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memory is the memory object to which this range belongs.

  • offset is the zero-based byte offset from the beginning of = the memory object.

  • size is either the size of range, or VK_WHOLE_SIZE to affect the range from offset to the end of the current mapping of the allocation.

Valid Usage
  • memory must be currently map= ped

  • If size is not equal to VK_WHOLE_SIZE, offs= et and size must specify a range co= ntained within the currently mapped range of memory

  • If size is equal to VK_WHOLE_SIZE, offset must be within the currently mapped range of memory

  • If size is equal to VK_WHOLE_SIZE, the end of the= current mapping of memory must be a = multiple of VkPhysicalDeviceLimits::nonCoherentAtomSi= ze bytes from the beginning of the memory object.

  • offset must be a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSi= ze

  • If size is not equal to VK_WHOLE_SIZE, size= must either be a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSi= ze, or offset plus size must equal the siz= e of memory.

Valid Usage (Implicit)
  • sType <= strong class=3D"purple">must be VK_STRUCTURE_TYPE_MAPPED_MEM= ORY_RANGE

  • pNext <= strong class=3D"purple">must be NULL

  • memory must be a valid VkDeviceMemory= handle

To unmap a memory object once host access to it is no longer needed by t= he application, call:

void vkUnmapMemory(
    VkDevice                                    device,
    VkDeviceMemory                              memory);
  • device is the logical device that owns the memory.

  • memory is the memory object to be unmapped.

Valid Usage
  • memory must be currently map= ped

Valid Usage (Implicit)
  • device <= strong class=3D"purple">must be a valid VkDevice hand= le

  • memory <= strong class=3D"purple">must be a valid VkDeviceMemory handle

  • memory must have been created, allocated, or retriev= ed from device

Host Synchronization
  • Host access to memory must be externally synchronized

10.2.2. Lazily Allocated Memory

If the memory object is allocated from a heap with the VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set, that object= =E2=80=99s backing memory may be provided by the implementat= ion lazily. The actual committed size of the memory may initially be as small as zero (or as large as the requested size), and monotonically increases as additional memory is needed.

A memory type with this flag set is only allowed to be bound to a VkImage whose usage flags include VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT.

Note

Using lazily allocated memory objects for framebuffer attachments that a= re not needed once a render pass instance has completed may allow some implementations to never allocate memory for such attachments.

To determine the amount of lazily-allocated memory that is currently committed for a memory object, call:

void vkGetDeviceMemoryCommitment(
    VkDevice                                    device,
    VkDeviceMemory                              memory,
    VkDeviceSize*                               pCommittedMemoryInBytes);
  • device is the logical device that owns the memory.

  • memory is the memory object being queried.

  • pCommittedMemoryInBytes is a pointer to a VkDeviceSiz= e value in which the number of bytes currently committed is returned, on success.

The implementation may update the comm= itment at any time, and the value returned by this query may be out of date= .

The implementation guarantees to allocate any committed memory from the heapIndex indicated by the memory type that the memory object was created with.

Valid Usage
  • memory must have been create= d with a memory type that reports VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT

Valid Usage (Implicit)
  • d= evice must be a valid VkDevi= ce handle

  • m= emory must be a valid VkDevi= ceMemory handle

  • pCommittedMemoryInBytes mus= t be a valid pointer to a VkDeviceSize value

  • memo= ry must have been created, allocat= ed, or retrieved from device

10.2.3. Protected Memory

Protected memory divides device memory into protected device me= mory and unprotected device memory.

Protected memory adds the following concepts:

  • Memory:

    • Unprotected device memory, which can b= e visible to the device and can be visible to the host

    • Protected device memory, which can be = visible to the device but must not be visible to the host

  • Resources:

    • Unprotected images and unprotected buffers, to which unprotected memory can be bound

    • Protected images and protected buffers, to which protected memory can be bound

  • Command buffers:

    • Unprotected command buffers, which can= be submitted to a device queue to execute unprotected queue operations

    • Protected command buffers, which can b= e submitted to a protected-capable device queue to execute protected queue operations

  • Device queues:

    • Unprotected device queues, to which unprotected command buffers can be submitted

    • Protected-capable device queues, to which unprotected command buffers or protected command buffers can be submi= tted

  • Queue submissions

    • Unprotected queue submissions, through which unprotected command buffers can be submitted

    • Protected queue submissions, through which protected command buffers can be submitted

  • Queue operations

    • Unprotected queue operations

      • Any read from or write to protected memory during unprotected queue operations results in undefined behavior but is subject to the inviolable rules below.

    • Protected queue operations

      • Any write to unprotected memory during protected queue operations results in undefined behavior but is subject to the inviolable rules below.

      • Except for framebuffer-space pipeline stages, compute shader stage, and transfer stage, any read from or write to protected memory during protected queue operations results in undefined behavior but is subject to the inviolable rules below.

      • Any queries during protected queue operations results in undefined behavior but is subject to the inviolable rules below.

Protected memory inviolable ru= les

Implementations must ensure that corre= ct usage or incorrect usage by an application does not affect the integrity of the memory protection system.<= /p>

The implementation must guarantee that= :

  • Protected device memory must not be vi= sible to the host.

  • Values written to unprotected device memory mus= t not be a function of data from protected memory.

Incorrect usage by an application of the memory protection system result= s in undefined behavior which may include proc= ess termination or device loss.

10.2.4. External Memory Handle Type= s

Android Hardware Buffer<= /h5>

Android=E2=80=99s NDK defines AHardwareBuffer objects, whic= h represent device memory that is shareable across processes and that can be accessed by a variety of media APIs and the hardware used to implement them. These Android hardware buffer objects may= be imported into VkDeviceMemory objects for access via Vulkan, or export= ed from Vulkan.

Android hardware buffer objects are reference-counted using Android NDK functions outside of the scope of this specification. A VkDeviceMemory imported from an Android hardware buff= er or that can be exported to an Android hardware buffer must acquire a reference to its AHardwareBuffer object, and must release this reference when the device memory is freed. During the host execution of a Vulkan command that has an Android hardware buffer as a parameter (including indirect parameters via pNext chains), the application must not decreme= nt the Android hardware buffer=E2=80=99s reference count to zero.

Android hardware buffers can be mapped= and unmapped for CPU access using the NDK functions. These lock and unlock APIs are considered to acquire and release ownership of the Android hardware buffer, and applications m= ust follow the rules described in External Resource Sharing to transfer ownership between the Vulkan instance and these native APIs.

Android hardware buffers can be shared= with external APIs and Vulkan instances on the same device, and also with foreign devices. When transferring ownership of the Android hardware buffer, the external an= d foreign special queue families described in Queue Family Ownership Transfer are no= t identical. All APIs which produce or consume Android hardware buffers are considered t= o use foreign devices, except OpenGL ES contexts and Vulkan logical devices that have matching device and driver UUIDs. Implementations may treat a transfer to o= r from the foreign queue family as if it were a transfer to or from the external queue family when the Android hardware buffer=E2=80=99s usage only permits it to be used on the same phys= ical device.

Android H= ardware Buffer Optimal Usages

Vulkan buffer and image usage flags do not correspond exactly to Android hardware buffer usage flags. When allocating Android hardware buffers with non-Vulkan APIs, if any AHARDWAREBUFFER_USAGE_GPU_* usage bits are included, by defaul= t the allocator must allocate the memory in suc= h a way that it supports Vulkan usages and creation flags in the usage equivalence table which do not have Android hardware buffer equivalents.

The VkAndroidHardwareBufferUsageAND= ROID structure can be attached to the pNext chain of a VkImageFormatPr= operties2 instance passed to vkGetPhysicalDeviceImageFormatPr= operties2 to obtain optimal Android hardware buffer usage flags for specific Vulkan resource creation parameters. Some usage flags returned by these commands are re= quired based on the input parameters, but additional vendor-specific usage flags (AHARDWAREBUFFER_USAGE_VENDOR_*) may<= /strong> also be returned. Any Android hardware buffer allocated with these vendor-specific usage flag= s and imported to Vulkan must only be bound= to resources created with parameters that are a subset of the parameters used to obtain the Android hardware buffer usage, since the memory may have been allocated in a way incompatible with other parameters. If an Android hardware buffer is successfully allocated with additional non-vendor-specific usage flags in addition to the recommended usage, it must support being used in the same ways = as an Android hardware buffer allocated with only the recommended usage, and also in ways indicated by th= e additional usage.

Android= Hardware Buffer External Formats

Android hardware buffers may represent= images using implementation-specific formats, layouts, color models, etc., which do not have Vulkan equivalents. Such external formats are commonly used by external image sources = such as video decoders or cameras. Vulkan can import Android hardware buffer= s that have external formats, but since the image contents are in an undiscoverable and possibly proprietary representation, images with external formats must<= /strong> only be used as sampled images, must only be sampled with a sampl= er that has Y=E2=80=99CBCR conversion enabled, and must have optimal tiling.

Android = Hardware Buffer Image Resources

Android hardware buffers have intrinsic width, height, format, and usage properties, so Vulkan images bound to memory imported from an Android hardware buffer must use dedicated alloca= tions: VkMemoryDedicatedRequirements::requiresDedicatedAllocati= on must be VK_TRUE for images created with VkExternalMemoryImageCreateInfo::handleTypes that= includes VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID. When creating an image that will be bound to an imported Android hardware buffer, the image creation parameters must be equivalent to the AHardwareBuffer properties as described by the valid usage of VkMemoryAllocateInfo. Similarly, device memory allocated for a dedicated image must not be exported to an Android hardware buffer until it has been bound to that image, and the implementation must return= an Android hardware buffer with properties derived from the image:

  • The width and height members of AHardwar= eBuffer_desc must be the same as the width and height members of VkImageCreateInfo::extent, respectively= .

  • The layers member of AHardwareBuffer_desc must be the same as the arrayLayers member of VkImageCreateInfo= .

  • The format member of AHardwareBuffer_desc must be equivalent to VkImageCreateInfo::format as defined= by AHardwareBuffer Format Equivalence.

  • The usage member of AHardwareBuffer_desc must include bits corresponding to bits included in VkImageCreateInfo:= :usage and VkImageCreateInfo::flags where such= a correspondence exists according to AHardwareBuffer Usage Equivalence. It may also include additional usage bits= , including vendor-specific usages. Presence of vendor usage bits may make th= e Android hardware buffer only usable in ways indicated by the image creation parameters, even when used outside Vulkan, in a similar way that allocating the Android hardware buffer with usage returned in VkAndroidHardwareBufferUsageANDROID.

Implementations may support fewer comb= inations of image creation parameters for images with Android hardware buffer external handle type than for non-external images. Support for a given set of parameters can= be determined by passing VkExternalImageFormatProperties to vkGetPhysicalDeviceImageFormatPr= operties2 with handleType set to VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID. Any Android hardware buffer successfully allocated outside Vulkan with usag= e that includes AHARDWAREBUFFER_USAGE_GPU_* must be supported when using equivalent Vulkan image parameters. If a given choice of image parameters are supported for import, they can also be used to create an image and memory that will be exported to an Android hardware buffer.

Table 13. AHardwareBuffer Format Equivalence
AHardwareBuffer Format Vulkan Format

AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM

VK_FORMAT_R8G8B8A8_UNORM

AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM

VK_FORMAT_R8G8B8A8_UNORM

AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM

VK_FORMAT_R8G8B8_UNORM

AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM

VK_FORMAT_R5G6B5_UNORM_PACK16

AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT

VK_FORMAT_R16G16B16A16_SFLOAT

AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM

VK_FORMAT_A2B10G10R10_UNORM_PACK32

AHARDWAREBUFFER_FORMAT_D16_UNORM

VK_FORMAT_D16_UNORM

AHARDWAREBUFFER_FORMAT_D24_UNORM

VK_FORMAT_X8_D24_UNORM_PACK32

AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT

VK_FORMAT_D24_UNORM_S8_UINT

AHARDWAREBUFFER_FORMAT_D32_FLOAT

VK_FORMAT_D32_SFLOAT

AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT

VK_FORMAT_D32_SFLOAT_S8_UINT

AHARDWAREBUFFER_FORMAT_S8_UINT

VK_FORMAT_S8_UINT

Table 14. AHardwareBuffer Usage Equivalence
AHardwareBuffer Usage Vulkan Usage or Creation Fl= ag

Non= e

VK_IMAGE_USAGE_TRANSFER_SRC_BIT

Non= e

VK_IMAGE_USAGE_TRANSFER_DST_BIT

AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE

VK_IMAGE_USAGE_SAMPLED_BIT

AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE

VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT

AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT

VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT

AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP

VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT

AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE

Non= e 2

AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT

VK_IMAGE_CREATE_PROTECTED_BIT

Non= e

VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT

Non= e

VK_IMAGE_CREATE_EXTENDED_USAGE_BIT

2

The AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE flag does not correspond to a Vulkan image usage or creation flag. Instead, its presence indicates that the Android hardware buffer contains a complete set of mip levels (VkImageCreateInfo::mipLevels is =E2=8C=88log2(max(width, h= eight))=E2=8C=89 + 1), and its absence indicates that the Android hardware buffer contains only a single mip level.

Note

When using VK_IMAGE_USAGE_MUTABLE_FORMAT_BIT with Android h= ardware buffer images, applications should use VkImageFormatListCreateInfoKHR to inform the implementation which view formats will be used with the image= . For some common sets of format, this allows some implementations to provide significantly better performance when accessing the image via Vulkan.

Android= Hardware Buffer Buffer Resources

Android hardware buffers with a format of AHARDWAREBUFFER_FORMAT_B= LOB and usage that includes AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER = can be used as the backing store for VkBuffer objects. Such Android hardware buffers have a size in bytes specified by their width; height and layers are both 1.

Unlike images, buffer resources backed by Android hardware buffers do no= t require dedicated allocations.

Exported AHardwareBuffer objects that do not have dedicated= images must have a format of AHARDWAREBUFF= ER_FORMAT_BLOB, usage must include AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER, width must equal the device memory allocation size, and height and layers must be 1.

10.2.5. Peer Memory Features

Peer memory is memory that is allocated for a given physical de= vice and then bound to a resource and accessed by a different physical device, in a logical device that represents multiple physical devices. Some ways of reading and writing peer memory may not be supported by a device.

To determine how peer memory can be ac= cessed, call:

void vkGetDeviceGroupPeerMemoryFeatures(
    VkDevice                                    device,
    uint32_t                                    heapIndex,
    uint32_t                                    localDeviceIndex,
    uint32_t                                    remoteDeviceIndex,
    VkPeerMemoryFeatureFlags*                   pPeerMemoryFeatures);

or the equivalent command

void vkGetDeviceGroupPeerMemoryFeaturesKHR(
    VkDevice                                    device,
    uint32_t                                    heapIndex,
    uint32_t                                    localDeviceIndex,
    uint32_t                                    remoteDeviceIndex,
    VkPeerMemoryFeatureFlags*                   pPeerMemoryFeatures);
  • device is the logical device that owns the memory.

  • heapIndex is the index of the memory heap from which the me= mory is allocated.

  • localDeviceIndex is the device index of the physical device= that performs the memory access.

  • remoteDeviceIndex is the device index of the physical devic= e that the memory is allocated for.

  • pPeerMemoryFeatures is a pointer to a bitmask of VkPeerMemoryFeatureFlagBits indicating whi= ch types of memory accesses are supported for the combination of heap, local, and remote devices.

Valid Usage
  • heapIndex must be less than = memoryHeapCount

  • localDeviceIndex must be a v= alid device index

  • remoteDeviceIndex must be a = valid device index

  • localDeviceIndex must not eq= ual remoteDeviceIndex

Valid Usage (Implicit)

Bits which may be set in the value ret= urned for vkGetDeviceGroupPeerMemoryFeatures:= :pPeerMemoryFeatures, indicating the supported peer memory features, are:

typedef enum VkPeerMemoryFeatur=
eFlagBits {
    VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT =3D 0x00000001<=
/span>,
    VK_PEER_MEMORY_FEATURE_COPY_DST_BIT =3D 0x00000002<=
/span>,
    VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT =3D 0x000000=
04,
    VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT =3D 0x000000=
08,
    VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHR =3D VK_PEER_MEMORY_FEATURE_COPY=
_SRC_BIT,
    VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHR =3D VK_PEER_MEMORY_FEATURE_COPY=
_DST_BIT,
    VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHR =3D VK_PEER_MEMORY_FEATURE_G=
ENERIC_SRC_BIT,
    VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHR =3D VK_PEER_MEMORY_FEATURE_G=
ENERIC_DST_BIT,
} VkPeerMemoryFeatureFlagBits;

or the equivalent

typedef VkPeerMemoryFeatureFlagBits VkPeerMemoryFeatureFlagBit=
sKHR;
  • VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT specifies that the memo= ry can be accessed as the source of a vkCmdCopyBuffer, vkCmdCopyImage, vkCmdCopyBufferToImage, or vkCmdCopyImageToBuffer command.

  • VK_PEER_MEMORY_FEATURE_COPY_DST_BIT specifies that the memo= ry can be accessed as the destination of a vkCmdCopyBuffer, vkCmdCopyImage, vkCmdCopyBufferToImage, or vkCmdCopyImageToBuffer command.

  • VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT specifies that the m= emory can be read as any memory access type.

  • VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT specifies that the m= emory can be written as any memory access type. Shader atomics are considered to be writes.

Note

The peer memory features of a memory heap also apply to any accesses tha= t may be performed during image layout transitions.

VK_PEER_MEMORY_FEATURE_COPY_DST_BIT must be supported for all host local heaps and for at least one device local heap.

If a device does not support a peer memory feature, it is still valid to= use a resource that includes both local and peer memory bindings with the corresponding access type as long as only the local bindings are actually accessed. For example, an application doing split-frame rendering would use framebuffer attachments that include both local and peer memory bindings, but would scissor the rendering to only update local memory.

typedef VkFlags VkPeerMemoryFeatureFlags;

or the equivalent

typedef VkPeerMemoryFeatureFlags VkPeerMemoryFeatureFlagsKHR;<=
/code>

VkPeerMemoryFeatureFlags is a bitmask type for setting a ma= sk of zero or more VkPeerMemoryFeatureFlagBits.

11. Resource Creation

Vulkan supports two primary resource types: buffers and ima= ges. Resources are views of memory with associated formatting and dimensionality= . Buffers are essentially unformatted arrays of bytes whereas images contain format information, can be multidimension= al and may have associated metadata.

11.1. Buffers

Buffers represent linear arrays of data which are used for various purpo= ses by binding them to a graphics or compute pipeline via descriptor sets or vi= a certain commands, or by directly specifying them as parameters to certain commands.

Buffers are represented by VkBuffer handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkBuffer)

To create buffers, call:

VkResult vkCreateB=
uffer(
    VkDevice                                    device,
    const VkBufferCreateInfo*             =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkBuffer*                                   pBuffer);
  • device is the logical device that creates the buffer object= .

  • pCreateInfo is a pointer to an instance of the VkBufferCreateInfo structure containing parameters affecting creation of the buffer.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pBuffer points to a VkBuffer handle in which = the resulting buffer object is returned.

Valid Usage
  • If the flags member of pCreateInfo includes VK_BUFFER_CREATE_SPARSE_BINDING_BIT, creating this VkBuf= fer must not cause the total required sparse = memory for all currently valid sparse resources on the device to exceed VkPhysicalDeviceLimits::sparseAddressSpaceSize

Valid Usage (Implicit)
  • device = must be a valid VkDevice han= dle

  • pCreateIn= fo must be a valid pointer to a va= lid VkBufferCreateInfo structure

  • If pAlloca= tor is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • pBuffer must be a valid pointer to a VkBu= ffer handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkBufferCreateInfo structure is defined as:

typedef struct VkBufferCreateIn=
fo {
    VkStructureType        sType;
    const void*            pNext;
    VkBufferCreateFlags    flags;
    VkDeviceSize           size;
    VkBufferUsageFlags     usage;
    VkSharingMode          sharingMode;
    uint32_t               queueFamilyIndexCount;
    const uint32_t*        pQueueFamilyInd=
ices;
} VkBufferCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkBufferCreat= eFlagBits specifying additional parameters of the buffer.

  • size is the size in bytes of the buffer to be created.

  • usage is a bitmask of VkBufferUsageF= lagBits specifying allowed usages of the buffer.

  • sharingMode is a VkSharingMode value spe= cifying the sharing mode of the buffer when it will be accessed by multiple queue families.

  • queueFamilyIndexCount is the number of entries in the pQueueFamilyIndices array.

  • pQueueFamilyIndices is a list of queue families that will a= ccess this buffer (ignored if sharingMode is not VK_SHARING_MODE_CONCURRENT).

editing-note

(Jon) Should the constraint on usage !=3D 0 be converted to a Valid Usag= e statement? See gitlab #854.

Valid Usage
  • size must be greater than 0

  • If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be = a valid pointer to an array of queueFamilyIndexCount uint32_t values

  • If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must b= e greater than 1

  • If sharingMode is VK_SHARING_MODE_CONCURRENT, eac= h element of pQueueFamilyIndices must = be unique and must be less than pQueueFamilyPropertyCount returned by either vkGetPhysicalDeviceQueueFamilyPro= perties or vkGetPhysicalDeviceQueueFamilyPr= operties2 for the physicalDevice that was used to create device

  • If the sparse bindings feature is not enabled, flags must not = contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT

  • If the sparse buffer residency feature is not enabled, flags must not contain VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT

  • If the sparse aliased residency feature is not enabled, flags must not contain VK_BUFFER_CREATE_SPARSE_ALIASED_BIT

  • If flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT<= /code> or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT

  • If the pNext chain contains an instance of VkExternalMemoryBufferCreateInfo, its= handleTypes member must only contain bits that are also in VkExternalBufferProperties::externalM= emoryProperties.compatibleHandleTypes, as returned by vkGetPhysicalDe= viceExternalBufferProperties with pExternalBufferInfo->handleType equal to any o= ne of the handle types specified in VkExternalMemoryBufferCreateInfo::handleTypes

  • If the protected memory feature is not enabled, flags must not contain VK_BUFFER_CREATE_PROTECTED_BIT

  • If any of the bits VK_BUFFER_CREATE_SPARSE_BINDING_BIT, VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT are set, VK_BUFFER_CREATE_PROTECTED_BIT must not also be set

  • If the pNext chain contains an instance of VkDedicatedAllocationBufferCreateI= nfoNV, and the dedicatedAllocation member of the chained structure is VK_TRUE, then flags must= not include VK_BUFFER_CREATE_SPARSE_BINDING_BIT, VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT

Valid Usage (Implicit)

Bits which can be set in VkBufferCreateInfo::usage, specifying usage behavior of a buffer, are:

typedef enum VkBufferUsageFlagB=
its {
    VK_BUFFER_USAGE_TRANSFER_SRC_BIT =3D 0x00000001,
    VK_BUFFER_USAGE_TRANSFER_DST_BIT =3D 0x00000002,
    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT =3D 0x0000=
0004,
    VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT =3D 0x0000=
0008,
    VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT =3D 0x00000010,
    VK_BUFFER_USAGE_STORAGE_BUFFER_BIT =3D 0x00000020,
    VK_BUFFER_USAGE_INDEX_BUFFER_BIT =3D 0x00000040,
    VK_BUFFER_USAGE_VERTEX_BUFFER_BIT =3D 0x00000080,
    VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT =3D 0x00000100<=
/span>,
    VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT =3D 0=
x00000200,
} VkBufferUsageFlagBits;
  • VK_BUFFER_USAGE_TRANSFER_SRC_BIT specifies that the buffer = can be used as the source of a transfer command (see the definition of VK_PIPELINE_STAGE_TRANSFER_= BIT).

  • VK_BUFFER_USAGE_TRANSFER_DST_BIT specifies that the buffer = can be used as the destination of a transfer command.

  • VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT specifies that the= buffer can be used to create a VkBufferVie= w suitable for occupying a VkDescriptorSet slot of type VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER.

  • VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT specifies that the= buffer can be used to create a VkBufferVie= w suitable for occupying a VkDescriptorSet slot of type VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.

  • VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT specifies that the buffe= r can be used in a VkDescriptorBufferInfo suitable for occupying a VkDescriptorSet slot either of type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC.

  • VK_BUFFER_USAGE_STORAGE_BUFFER_BIT specifies that the buffe= r can be used in a VkDescriptorBufferInfo suitable for occupying a VkDescriptorSet slot either of type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC.

  • VK_BUFFER_USAGE_INDEX_BUFFER_BIT specifies that the buffer = is suitable for passing as the buffer parameter to vkCmdBindIndexBuffer.

  • VK_BUFFER_USAGE_VERTEX_BUFFER_BIT specifies that the buffer= is suitable for passing as an element of the pBuffers array to vkCmdBindVertexBuffers.

  • VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT specifies that the buff= er is suitable for passing as the buffer parameter to vkCmdDrawIndirect, vkCmdDrawIndexedIndirect, or vkCmdDispatchIndirect. It is also suitable for passing as the buffer member of VkIndirectCommandsTokenNVX, or sequencesCountBuffer or sequencesIndexBuffer member of VkCmdProcessCommandsInfoN= VX

  • VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT specifies tha= t the buffer is suitable for passing as the buffer parameter to vkCmdBeginConditionalRenderingEXT.

typedef VkFlags VkBufferUsageFlags;

VkBufferUsageFlags is a bitmask type for setting a mask of = zero or more VkBufferUsageFlagBits.

Bits which can be set in VkBufferCreateInfo::flags, specifying additional parameters of a buffer, are:

typedef enum VkBufferCreateFlag=
Bits {
    VK_BUFFER_CREATE_SPARSE_BINDING_BIT =3D 0x00000001<=
/span>,
    VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT =3D 0x0000000=
2,
    VK_BUFFER_CREATE_SPARSE_ALIASED_BIT =3D 0x00000004<=
/span>,
    VK_BUFFER_CREATE_PROTECTED_BIT =3D 0x00000008,
} VkBufferCreateFlagBits;
  • VK_BUFFER_CREATE_SPARSE_BINDING_BIT specifies that the buff= er will be backed using sparse memory binding.

  • VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT specifies that the bu= ffer can be partially backed using sparse memo= ry binding. Buffers created with this flag must also = be created with the VK_BUFFER_CREATE_SPARSE_BINDING_BIT flag.

  • VK_BUFFER_CREATE_SPARSE_ALIASED_BIT specifies that the buff= er will be backed using sparse memory binding with memory ranges that might also simultaneously be backing another buffer (or another portion of the same buffer). Buffers created with this flag must also = be created with the VK_BUFFER_CREATE_SPARSE_BINDING_BIT flag.

  • VK_BUFFER_CREATE_PROTECTED_BIT specifies that the buffer is= a protected buffer.

See Sparse Resource Features an= d Physical Device Features for details of the sparse memory features supported on a device.

typedef VkFlags VkBufferCreateFlags;

VkBufferCreateFlags is a bitmask type for setting a mask of= zero or more VkBufferCreateFlagBits.

If the pNext chain includes a VkDedicatedAllocationBufferCreateInfoNV structure, then that s= tructure includes an enable controlling whether the buffer will have a dedicated memory allocation bound to it.

The VkDedicatedAllocationBufferCreateInfoNV structure is de= fined as:

typedef struct VkDedicatedAlloc=
ationBufferCreateInfoNV {
    VkStructureType    sType;
    const void*        pNext;
    VkBool32           dedicatedAllocation;
} VkDedicatedAllocationBufferCreateInfoNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • dedicatedAllocation specifies whether the buffer will have = a dedicated allocation bound to it.

Valid Usage (Implicit)
  • = sType must be VK_STRUC= TURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV

To define a set of external memory handle types that may be used as backing store for a buffer, add a VkExternalMemor= yBufferCreateInfo structure to the pNext chain of the VkBufferCreateIn= fo structure. The VkExternalMemoryBufferCreateInfo structure is defined as:<= /p>

typedef struct VkExternalMemory=
BufferCreateInfo {
    VkStructureType                    sType;
    const void*                        pNext;
    VkExternalMemoryHandleTypeFlags    handleTypes;
} VkExternalMemoryBufferCreateInfo;

or the equivalent

typedef VkExternalMemoryBufferCreateInfo VkExternalMemoryBuffe=
rCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleTypes is a bitmask of VkExternalMemoryHandleTypeFlagBits = specifying one or more external memory handle types.

Valid Usage (Implicit)

To destroy a buffer, call:

void vkDestroyBuffer(
    VkDevice                                    device,
    VkBuffer                                    buffer,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the buffer.

  • buffer is the buffer to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to buffer, either directly o= r via a VkBufferView, must hav= e completed execution

  • If VkAllocationCallbacks were provided when buffer was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when buffer was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device= must be a valid VkDevice ha= ndle

  • If buffer is not VK_NULL_HANDLE, buffer must be a valid VkBuffer handle

  • If pAlloc= ator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • If buffer= is a valid handle, it must have been cre= ated, allocated, or retrieved from device

Host Synchronization
  • Host access to buffer must be externally synchronized

11.2. Buffer Views

A buffer view represents a contiguous range of a buffer and a s= pecific format to be used to interpret the data. Buffer views are used to enable shaders to access buffer contents interpreted as formatted data. In order to create a valid buffer view, the buffer must have been created with at least one of the following usage flags:

  • VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT

  • VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT

Buffer views are represented by VkBufferView handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkBufferView)

To create a buffer view, call:

VkResult vkCreateB=
ufferView(
    VkDevice                                    device,
    const VkBufferViewCreateInfo*         =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkBufferView*                               pView);
  • device is the logical device that creates the buffer view.<= /p>

  • pCreateInfo is a pointer to an instance of the VkBufferViewCreateInfo structure containing parameters to be u= sed to create the buffer.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pView points to a VkBufferView handle in = which the resulting buffer view object is returned.

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • pCrea= teInfo must be a valid pointer to = a valid VkBufferViewCreateInfo structure

  • If pAl= locator is not NULL, pAllocator must be a valid pointer to a valid VkAllocati= onCallbacks structure

  • pView must be a valid pointer to a VkBu= fferView handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkBufferViewCreateInfo structure is defined as:

typedef struct VkBufferViewCrea=
teInfo {
    VkStructureType            sType;
    const void*                pNext;
    VkBufferViewCreateFlags    flags;
    VkBuffer                   buffer;
    VkFormat                   format;
    VkDeviceSize               offset;
    VkDeviceSize               range;
} VkBufferViewCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • buffer is a VkBuffer on which the view will b= e created.

  • format is a VkFormat describing the format of= the data elements in the buffer.

  • offset is an offset in bytes from the base address of the b= uffer. Accesses to the buffer view from shaders use addressing that is relative to this starting offset.

  • range is a size in bytes of the buffer view. If range is equal to VK_WHOLE_SIZE, the range fro= m offset to the end of the buffer is used. If VK_WHOLE_SIZE is used and the remaining size of the buffer = is not a multiple of the element size of format, then the nearest smaller multiple is used.

Valid Usage
  • offset must be less than the= size of buffer

  • offset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment

  • If range is not equal to VK_WHOLE_SIZE, ran= ge must be greater than 0

  • If range is not equal to VK_WHOLE_SIZE, ran= ge must be a multiple of the element size of format

  • If range is not equal to VK_WHOLE_SIZE, ran= ge divided by the element size of format must be less than or equal to VkPhysicalDeviceLimits::maxTexelBufferElements

  • If range is not equal to VK_WHOLE_SIZE, the sum o= f offset and range must be less than or equal to the size of buffer

  • buffer must have been create= d with a usage value containing at least one of VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT

  • If buffer was created with usage containing VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, format = must be supported for uniform texel buffers, as specified by the VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties

  • If buffer was created with usage containing VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, format = must be supported for storage texel buffers, as specified by the VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties

  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_BUFFER_= VIEW_CREATE_INFO

  • pNext must be NULL

  • flags= must be 0

  • buffer= must be a valid VkBuffer handle

  • format= must be a valid VkForma= t value

typedef VkFlags VkBufferViewCreateFlags;

VkBufferViewCreateFlags is a bitmask type for setting a mas= k, but is currently reserved for future use.

To destroy a buffer view, call:

void vkDestroyBufferView(
    VkDevice                                    device,
    VkBufferView                                bufferView,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the buffer view.=

  • bufferView is the buffer view to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to bufferView must have completed execution

  • If VkAllocationCallbacks were provided when bufferView was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when bufferVie= w was created, pAllocator must= be NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • If bu= fferView is not VK_NULL_HANDLE, bufferView= must be a valid VkBufferVie= w handle

  • If pA= llocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocat= ionCallbacks structure

  • If buffe= rView is a valid handle, it must h= ave been created, allocated, or retrieved from device

Host Synchronization
  • Host access to bufferView must be externally synchronized

11.3. Images

Images represent multidimensional - up to 3 - arrays of data which can be used for various purposes (e.g. attachments, textures), by binding them to = a graphics or compute pipeline via descriptor sets, or by directly specifying them as parameters to certain commands.

Images are represented by VkImage handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkImage)

To create images, call:

VkResult vkCreateI=
mage(
    VkDevice                                    device,
    const VkImageCreateInfo*              =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkImage*                                    pImage);
  • device is the logical device that creates the image.

  • pCreateInfo is a pointer to an instance of the VkImageCreateInfo structure containing parameters to be used t= o create the image.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pImage points to a VkImage handle in which the= resulting image object is returned.

Valid Usage
  • If the flags member of pCreateInfo includes VK_IMAGE_CREATE_SPARSE_BINDING_BIT, creating this VkImag= e must not cause the total required sparse = memory for all currently valid sparse resources on the device to exceed VkPhysicalDeviceLimits::sparseAddressSpaceSize

Valid Usage (Implicit)
  • device <= strong class=3D"purple">must be a valid VkDevice hand= le

  • pCreateInf= o must be a valid pointer to a val= id VkImageCreateInfo structure

  • If pAllocat= or is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • pImage <= strong class=3D"purple">must be a valid pointer to a VkImage= handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkImageCreateInfo structure is defined as:

typedef struct VkImageCreateInf=
o {
    VkStructureType          sType;
    const void*              pNext;
    VkImageCreateFlags       flags;
    VkImageType              imageType;
    VkFormat                 format;
    VkExtent3D               extent;
    uint32_t                 mipLevels;
    uint32_t                 arrayLayers;
    VkSampleCountFlagBits    samples;
    VkImageTiling            tiling;
    VkImageUsageFlags        usage;
    VkSharingMode            sharingMode;
    uint32_t                 queueFamilyIndexCount;
    const uint32_t*          pQueueFamilyI=
ndices;
    VkImageLayout            initialLayout;
} VkImageCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkImageCreateF= lagBits describing additional parameters of the image.

  • imageType is a VkImageType value specifyin= g the basic dimensionality of the image. Layers in array textures do not count as a dimension for the purposes of the image type.

  • format is a VkFormat describing the format an= d type of the data elements that will be contained in the image.

  • extent is a VkExtent3D describing the numbe= r of data elements in each dimension of the base level.

  • mipLevels describes the number of levels of detail availabl= e for minified sampling of the image.

  • arrayLayers is the number of layers in the image.

  • samples is the number of sub-data element samples in the im= age as defined in VkSampleCountFlagBits. See Multisampling.

  • tiling is a VkImageTiling value specifyi= ng the tiling arrangement of the data elements in memory.

  • usage is a bitmask of VkImageUsageFla= gBits describing the intended usage of the image.

  • sharingMode is a VkSharingMode value spe= cifying the sharing mode of the image when it will be accessed by multiple queue families.

  • queueFamilyIndexCount is the number of entries in the pQueueFamilyIndices array.

  • pQueueFamilyIndices is a list of queue families that will a= ccess this image (ignored if sharingMode is not VK_SHARING_MODE_CONCURRENT).

  • initialLayout is a VkImageLayout value s= pecifying the initial VkImageLayout of all image subresources of the i= mage. See Image Layouts.

Images created with tiling equal to VK_IMAGE_TILING_L= INEAR have further restrictions on their limits and capabilities compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL. Creation of images with tiling VK_IMAGE_TILING_LINEAR may not be supported unless other parameters meet all of the constraints:

  • imageType is VK_IMAGE_TYPE_2D

  • format is not a depth/stencil format

  • mipLevels is 1

  • arrayLayers is 1

  • samples is VK_SAMPLE_COUNT_1_BIT

  • usage only includes VK_IMAGE_USAGE_TRANSFER_SRC_BIT and/or VK_IMAGE_USAGE_TRANSFER_DST_BIT

Implementations may support additional= limits and capabilities beyond those listed above.

To query an implementation=E2=80=99s specific capabilities for a given c= ombination of format, imageType, tiling, = usage, VkExternalMemoryImageCreateInfo::handleTypes and flags, call vkGetPhysicalDeviceImageFormatPr= operties2. The return value specifies whether that combination of image settings is supported. On success, the VkImageFormatProperties output parameter speci= fies the set of valid samples bits and the limits for extent, mipLevels, arrayLayers, and maxResourceSize= . Even if vkGetPhysicalDeviceImageFormatPr= operties2. returns success and the parameters to vkCreateImage are all wi= thin the returned limits, vkCreateImage must fail and return VK_ERROR_OUT_OF_DEVICE_MEMORY if the resulting size of the ima= ge would be larger than maxResourceSize.

To determine the set of valid usage bits for a given format= , call vkGetPhysicalDeviceFormatProperties.

Note

For images created without VK_IMAGE_CREATE_EXTENDED_USAGE_BIT a usage bit is valid if it is supported for the format the image= is created with.

For images created with VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = a usage bit is valid if it is supported for at least one of the = formats a VkImageView created from the image = can have (see Image Views for more detail).

Valid Usage
  • If the pNext chain does not contain an instance of VkExternalFormatANDROID, or if format is not VK_FORMAT_UNDEFINED, the combination of format, imageType, tiling, usage, and = flags must be supported, as indicated by a VK_SUCCESS return value from vkGetPhysicalDeviceImageFormatProperties invoked with the same values passed to the corresponding parameters.

  • If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be = a valid pointer to an array of queueFamilyIndexCount uint32_t values

  • If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must b= e greater than 1

  • If sharingMode is VK_SHARING_MODE_CONCURRENT, eac= h element of pQueueFamilyIndices must = be unique and must be less than pQueueFamilyPropertyCount returned by either vkGetPhysicalDeviceQueueFamilyPro= perties or vkGetPhysicalDeviceQueueFamilyPr= operties2 for the physicalDevice that was used to create device

  • If the pNext chain contains an instance of VkExternalFormatANDROID, and its member = externalFormat is non-zero the format must be = VK_FORMAT_UNDEFINED.

  • If the pNext chain does not contain an instance of VkExternalFormatANDROID, or does and its membe= r externalFormat is 0 the format must not be VK_FORMAT_UNDEFINED.

  • extent::width must be greater than 0.

  • extent::height must be greater than 0.

  • extent::depth must be greater than 0.

  • mipLevels must be greater th= an 0

  • arrayLayers must be greater = than 0

  • If flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, imageType must be VK_I= MAGE_TYPE_2D

  • If flags contains VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BI= T, imageType must be VK_I= MAGE_TYPE_3D

  • If imageType is VK_IMAGE_TYPE_1D, extent.wi= dth must be less than or equal to VkPhysicalDeviceLimits::maxImageDimension1D, or VkImageFormatProperties::maxExtent.width (as retu= rned by vkGetPhysicalDeviceImageFormatProperties with format, imageType, tiling, usage, and = flags equal to those in this structure) - whichever is higher

  • If imageType is VK_IMAGE_TYPE_2D and flags<= /code> does not contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.widt= h and extent.height must be le= ss than or equal to VkPhysicalDeviceLimits::maxImageDimension2D, or VkImageFormatProperties::maxExtent.width/he= ight (as returned by vkGetPhysicalDeviceImageFormatProperties with format, imageType, tiling, usa= ge, and flags equal to those in this structure) - whichever is higher<= /p>

  • If imageType is VK_IMAGE_TYPE_2D and flags<= /code> contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width= and extent.height must be less t= han or equal to VkPhysicalDeviceLimits::maxImageDimensionCube, or VkImageFormatProperties::maxExtent.width/he= ight (as returned by vkGetPhysicalDeviceImageFormatProperties with format, imageType, tiling, usa= ge, and flags equal to those in this structure) - whichever is higher<= /p>

  • If imageType is VK_IMAGE_TYPE_2D and flags<= /code> contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width= and extent.height must be equal = and arrayLayers must be greater than or equal to 6

  • If imageType is VK_IMAGE_TYPE_3D, extent.wi= dth, extent.height and extent.depth must be less than or equal to VkPhysicalDeviceLimits::maxImageDimension3D, o= r VkImageFormatProperties::maxExtent.width/he= ight/depth (as returned by vkGetPhysicalDeviceImageFormatProperties with format, imageType, tiling, usa= ge, and flags equal to those in this structure) - whichever is higher<= /p>

  • If imageType is VK_IMAGE_TYPE_1D, both exte= nt.height and extent.depth must be 1

  • If imageType is VK_IMAGE_TYPE_2D, extent.de= pth must be 1

  • mipLevels must be less than = or equal to =E2=8C=8Alog2(max(extent.width, = extent.height, extent.depth))=E2=8C=8B + 1.

  • mipLevels must be less than = or equal to VkImageFormatProperties::maxMipLevels (as returne= d by vkGetPhysicalDeviceImageFormatProperties with format, imageType, tiling, usage, and = flags equal to those in this structure)

  • arrayLayers must be less tha= n or equal to VkImageFormatProperties::maxArrayLayers (as retur= ned by vkGetPhysicalDeviceImageFormatProperties with format, imageType, tiling, usage, and = flags equal to those in this structure)

  • If imageType is VK_IMAGE_TYPE_3D, arrayLaye= rs must be 1.

  • If samples is not VK_SAMPLE_COUNT_1_BIT, im= ageType must be VK_IMAGE_TYPE_2D, flags must not contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, tiling must be VK_IMAGE_TILING_OPTIMAL, and mipLevels must be equal to 1

  • If usage includes VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BI= T, then bits other than VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, and VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT m= ust not be set

  • If usage includes VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, extent.width= must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferWidth

  • If usage includes VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, extent.height must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferHeight

  • If usage includes VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BI= T, usage must also contain at l= east one of VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT.

  • samples must be a bit value = that is set in VkImageFormatProperties::sampleCounts returned by vkGetPhysicalDeviceImageFormatProperties with format, imageType, tiling, usage, and = flags equal to those in this structure

  • If the multisampled storage images feature is not enabled, and usage contains VK_IMAGE_USAGE_STORAGE_BIT, samples must be VK_SAMPLE_COUNT_1_BIT

  • If the sparse bindings feature is not enabled, flags must not = contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT

  • If the sparse aliased residency feature is not enabled, flags must not contain VK_IMAGE_CREATE_SPARSE_ALIASED_BIT

  • If imageType is VK_IMAGE_TYPE_1D, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT

  • If the sparse residency for 2D images feature is not enabled, and imageType is VK_IMAGE_TYPE_2D, flags = must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT

  • If the sparse residency for 3D images feature is not enabled, and imageType is VK_IMAGE_TYPE_3D, flags = must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT

  • If the sparse residency for images with 2 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_2_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT

  • If the sparse residency for images with 4 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_4_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT

  • If the sparse residency for images with 8 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_8_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT

  • If the sparse residency for images with 16 samples feature is not enabled, imageType i= s VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_16_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT

  • If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT

  • If any of the bits VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT are set, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT must not also be set

  • If the protected memory feature is not enabled, flags must not contain VK_IMAGE_CREATE_PROTECTED_BIT.

  • If any of the bits VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT are set, VK_IMAGE_CREATE_PROTECTED_BIT must not also be set.

  • If the pNext chain contains an instance of VkExternalMemoryImageCreateInfoNV, i= t must not contain an instance of VkExternalMemoryImageCreateInf= o.

  • If the pNext chain contains an instance of VkExternalMemoryImageCreateInfo, its <= code>handleTypes member must only contain bits that are also in VkExternalImageFormatProperties::externalMemoryProperties.compatibleHandleTypes, as returned by vkGetPhysicalDevi= ceImageFormatProperties2 with format, imageType, tiling, usa= ge, and flags equal to those in this structure, and with an instance o= f VkPhysicalDeviceExternalImageForma= tInfo in the pNext chain, with a handleType equal to any one of the handle types specifi= ed in VkExternalMemoryImageCreateInfo::handleTypes

  • If the pNext chain contains an instance of VkExternalMemoryImageCreateInfoNV, i= ts handleTypes member must only contain bits that are also in VkExternalImageFormatPropertiesNV::<= code>externalMemoryProperties.compatibleHandleTypes, as returned by vkGetPhy= sicalDeviceExternalImageFormatPropertiesNV with format, imageType, tiling, usage, and flags equal to those in this structure, and with externalHandleType equal to any one of the handle types specif= ied in VkExternalMemoryImageCreateInfoNV= ::handleTypes

  • If the logical device was created with VkDeviceGroupDeviceCreateInfo::phy= sicalDeviceCount equal to 1, flags must not contain VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT

  • If flags contains VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, then mipLevels must be one, arrayLayers must be one, imageType must be VK_I= MAGE_TYPE_2D, and tiling must<= /strong> be VK_IMAGE_TILING_OPTIMAL

  • If flags contains VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, then fo= rmat must be a bloc= k-compressed image format, an ETC compressed image format, or an ASTC compressed image format.

  • If flags contains VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, then fl= ags must also contain VK_IMAGE_CREATE_M= UTABLE_FORMAT_BIT.

  • initialLayout must be = VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED.

  • If the pNext chain includes a VkExternalMemoryImageCreateInfo or VkExternalMemoryImageCreateInfoNV structure whose handleTypes member is not 0, = initialLayout must be VK_IMAGE_LAYOUT_UNDEFIN= ED

  • If the image format is one of those listed in Formats requiring samp= ler Y=E2=80=99CBCR conversion for VK_IMAGE_ASPE= CT_COLOR_BIT image views:

    • mipLevels must be 1

    • samples must be VK_SAMPLE_COUNT_1_BIT

    • imageType must be V= K_IMAGE_TYPE_2D

    • arrayLayers must be 1

  • If tiling is VK_IMAGE_TILING_OPTIMAL, forma= t is a multi-planar format, and VkFormatProperties::optimalTilingFeatures (as ret= urned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_DISJOINT_BIT<= /code>, flags must not contain VK_IMAGE_CREATE_DISJOINT_BIT

  • If tiling is VK_IMAGE_TILING_LINEAR, format= is a multi-planar format, and VkFormatProperties::linearTilingFeatures (as retu= rned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_DISJOINT_BIT<= /code>, flags must not contain VK_IMAGE_CREATE_DISJOINT_BIT

  • If format is not a multi-planar format, and fla= gs does not include VK_IMAGE_CREATE_ALIAS_BIT, flags must not contain VK_IMAGE_CREATE_DISJOINT_BIT

  • If flags contains VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT format must be a depth or de= pth/stencil format

  • If the pNext chain includes a VkExternalMemoryImageCreateInfo struct= ure whose handleTypes member includes VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:

    • imageType must be V= K_IMAGE_TYPE_2D

    • mipLevels must either be = 1 or equal to =E2=8C=8Alog2(max(extent.width, = extent.height, extent.depth))=E2=8C=8B + 1.

    • If format is not VK_FORMAT_UNDEFINED, then format, imageType, tiling, usage, flag= s, mipLevels, and samples m= ust be supported with VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID external memory handle types according to vkGetPhysicalDeviceImageFormatPr= operties2

    • If format is VK_FORMAT_UNDEFINED, then the pNext chain must include a VkExternalFormatANDROID structure whose externalFormat member is not 0

  • If the pNext chain includes a VkExter= nalFormatANDROID structure whose externalFormat member is not 0:

    • format must be VK_F= ORMAT_UNDEFINED

    • flags must not include VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT

    • usage must not include an= y usages except VK_IMAGE_USAGE_SAMPLED_BIT

    • tiling must be VK_I= MAGE_TILING_OPTIMAL

Valid Usage (Implicit)

If the pNext chain includes a VkDedicatedAllocationImageCreateInfoNV structure, then that st= ructure includes an enable controlling whether the image will have a dedicated memory allocation bound to it.

The VkDedicatedAllocationImageCreateInfoNV structure is def= ined as:

typedef struct VkDedicatedAlloc=
ationImageCreateInfoNV {
    VkStructureType    sType;
    const void*        pNext;
    VkBool32           dedicatedAllocation;
} VkDedicatedAllocationImageCreateInfoNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • dedicatedAllocation specifies whether the image will have a dedicated allocation bound to it.

Note

Using a dedicated allocation for color and depth/stencil attachments or other large images may improve performanc= e on some devices.

Valid Usage
  • If dedicatedAllocation is VK_TRUE, VkImageCreateInfo::flags must not include VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT

Valid Usage (Implicit)
  • <= code>sType must be VK_STRUCT= URE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV

If the pNext chain includes a VkExternalMemoryImageCr= eateInfoNV structure, then that structure defines a set of external memory handle type= s that may be used as backing store for the= image.

The VkExternalMemoryImageCreateInfoNV structure is defined = as:

typedef struct VkExternalMemory=
ImageCreateInfoNV {
    VkStructureType                      sType;
    const void*                          pNext;
    VkExternalMemoryHandleTypeFlagsNV    handleTypes;
} VkExternalMemoryImageCreateInfoNV;

To create an image with an external format, include an instance of VkExternalFormatANDROID in = the pNext chain of VkImageCreateInfo. VkExternalFormatANDROID is defined as:

typedef struct VkExternalFormat=
ANDROID {
    VkStructureType    sType;
    void*              pNext;
    uint64_t           externalFormat;
} VkExternalFormatANDROID;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • externalFormat is an implementation-defined identifier for = the external format

If externalFormat is zero, the effect is as if the VkExternalFormatANDROID structure was not present. Otherwise, the image will have the specified external format.<= /p>

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_EXTERN= AL_FORMAT_ANDROID

The VkImageFormatListCreateInfoKHR structure is defined as:=

typedef struct VkImageFormatLis=
tCreateInfoKHR {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           viewFormatCount;
    const VkFormat*    pViewFormats;
} VkImageFormatListCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • viewFormatCount is the number of entries in the pView= Formats array.

  • pViewFormats is an array which lists of all formats which <= strong class=3D"purple">can be used when creating views of this image.

Valid Usage
  • If viewFormatCount is not 0, all of the formats i= n the pViewFormats array must be c= ompatible with the format specified in the format field of VkImageCreateInfo, as desc= ribed in the compatibility table.

  • If VkImageCreateInfo::flags does not contain VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, viewFormatCount must be 0 or 1.

  • If viewFormatCount is not 0, VkImageCreateInfo::format must be in pViewFormats.

Valid Usage (Implicit)

Bits which can be set in VkImageCreateInfo::usage, specifying intended usage of an image, are:

typedef enum VkImageUsageFlagBi=
ts {
    VK_IMAGE_USAGE_TRANSFER_SRC_BIT =3D 0x00000001,
    VK_IMAGE_USAGE_TRANSFER_DST_BIT =3D 0x00000002,
    VK_IMAGE_USAGE_SAMPLED_BIT =3D 0x00000004,
    VK_IMAGE_USAGE_STORAGE_BIT =3D 0x00000008,
    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT =3D 0x00000010<=
/span>,
    VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT =3D 0x0=
0000020,
    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT =3D 0x00000=
040,
    VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT =3D 0x00000080<=
/span>,
} VkImageUsageFlagBits;
  • VK_IMAGE_USAGE_TRANSFER_SRC_BIT specifies that the image can be used as the source of a transfer command.

  • VK_IMAGE_USAGE_TRANSFER_DST_BIT specifies that the image can be used as the destination of a transfer command.

  • VK_IMAGE_USAGE_SAMPLED_BIT specifies that the image can be used to create a VkImageView suitable for occupying a VkDescriptorSet slot either of type VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and be sampled by a shader.

  • VK_IMAGE_USAGE_STORAGE_BIT specifies that the image can be used to create a VkImageView suitable for occupying a VkDescriptorSet slot of type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE.

  • VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT specifies that the imag= e can be used to create a VkImageView suitable for use as a color or resolve attachment in a VkFramebuffer.

  • VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT specifies that = the image can be used to create a VkIma= geView suitable for use as a depth/stencil attachment in a VkFramebuffer.

  • VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT specifies that the = memory bound to this image will have been allocated with the VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT (see Memory Al= location for more detail). This bit can be set for any image that can be used to create a VkImageView suitable for use as a color, resolve, depth/stenci= l, or input attachment.

  • VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT specifies that the imag= e can be used to create a VkImageView suitable for occupying VkDescriptorSet slot of type VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; be read from a shader as = an input attachment; and be used as an input attachment in a framebuffer.

typedef VkFlags VkImageUsageFlags;

VkImageUsageFlags is a bitmask type for setting a mask of z= ero or more VkImageUsageFlagBits.

Bits which can be set in VkImageCreateInfo::flags, specifying additional parameters of an image, are:

typedef enum VkImageCreateFlagB=
its {
    VK_IMAGE_CREATE_SPARSE_BINDING_BIT =3D 0x00000001,
    VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT =3D 0x00000002=
,
    VK_IMAGE_CREATE_SPARSE_ALIASED_BIT =3D 0x00000004,
    VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT =3D 0x00000008,
    VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT =3D 0x00000010<=
/span>,
    VK_IMAGE_CREATE_ALIAS_BIT =3D 0x00000400,
    VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT =3D 0x00000040,
    VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT =3D 0x00000=
020,
    VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT =3D 0x00000080,
    VK_IMAGE_CREATE_EXTENDED_USAGE_BIT =3D 0x00000100,
    VK_IMAGE_CREATE_PROTECTED_BIT =3D 0x00000800=
,
    VK_IMAGE_CREATE_DISJOINT_BIT =3D 0x00000200,
    VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT =3D 0x00001000,
    VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR =3D VK_IMAGE_CREATE=
_SPLIT_INSTANCE_BIND_REGIONS_BIT,
    VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR =3D VK_IMAGE_CREATE_2D_ARRA=
Y_COMPATIBLE_BIT,
    VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR =3D VK_IMAGE_CREATE=
_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT,
    VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR =3D VK_IMAGE_CREATE_EXTENDED_USA=
GE_BIT,
    VK_IMAGE_CREATE_DISJOINT_BIT_KHR =3D VK_IMAGE_CREATE_DISJOINT_BIT,
    VK_IMAGE_CREATE_ALIAS_BIT_KHR =3D VK_IMAGE_CREATE_ALIAS_BIT,
} VkImageCreateFlagBits;
  • VK_IMAGE_CREATE_SPARSE_BINDING_BIT specifies that the image= will be backed using sparse memory binding.

  • VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT specifies that the ima= ge can be partially backed using sparse memory binding. Images created with this flag must also b= e created with the VK_IMAGE_CREATE_SPARSE_BINDING_BIT flag.

  • VK_IMAGE_CREATE_SPARSE_ALIASED_BIT specifies that the image= will be backed using sparse memory binding with memory ranges that might also simultaneously be backing another image (or another portion of the same image). Images created with this flag must also b= e created with the VK_IMAGE_CREATE_SPARSE_BINDING_BIT flag

  • VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT specifies that the image= can be used to create a VkImageView with a different format from t= he image. For multi-planar formats, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT specifies that a VkImageView can be created of a plane of the image.

  • VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT specifies that the imag= e can be used to create a VkImageView of type VK_IMAGE_VIEW_TYPE_CUBE or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY= .

  • VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT specifies that the = image can be used to create a VkImageView= of type VK_IMAGE_VIEW_TYPE_2D or VK_IMAGE_VIEW_TYPE_2D_ARRAY.

  • VK_IMAGE_CREATE_PROTECTED_BIT specifies that the image is a protected image.

  • VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT specifies t= hat the image can be used with a non-zero value o= f the splitInstanceBindRegionCount member of a VkBindImageMemoryDeviceGroupInfo stru= cture passed into vkBindImageMemory2. This flag also has the effect of making the image use the standard sparse image block dimensions.

  • VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT specifies t= hat the image having a compressed format can be u= sed to create a VkImageView with an uncompressed format where each texel in th= e image view corresponds to a compressed texel block of the image.

  • VK_IMAGE_CREATE_EXTENDED_USAGE_BIT specifies that the image= can be created with usage flags that are not supported for the format the image is created with but are supported for at least one format a VkImageView created from the image ca= n have.

  • VK_IMAGE_CREATE_DISJOINT_BIT specifies that an image with a multi-planar format must have each plane separatel= y bound to memory, rather than having a single memory binding for the whole image; the presence of this bit distinguishes a disjoint image from an image without this bit = set.

  • VK_IMAGE_CREATE_ALIAS_BIT specifies that two images created= with the same creation parameters and aliased to the same memory can interpret the contents of the memory consistently with each other, subject to the rules described in the Memory Aliasing section. This flag further specifies that each plane of a disjoint imag= e can share an in-memory non-linear representation with single-plane images, and that a single-plane image can sha= re an in-memory non-linear representation with a plane of a multi-planar disjoint image, according to the rules in Compatible formats = of planes of multi-planar formats. If the pNext chain includes a VkExternalMemoryImageCreateInfo or VkExternalMemoryImageCreateInfoNV structure whose handleTypes member is not 0, = it is as if VK_IMAGE_CREATE_ALIAS_BIT is set.

  • VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT specifies that an image with a depth or depth/stencil format can be used with custom sample locations when used as a depth/stencil attachment.

typedef VkFlags VkImageCreateFlags;

VkImageCreateFlags is a bitmask type for setting a mask of = zero or more VkImageCreateFlagBits.

Possible values of VkImageCreateInfo::image= Type, specifying the basic dimensionality of an image, are:

typedef enum VkImageType {
    VK_IMAGE_TYPE_1D =3D 0,
    VK_IMAGE_TYPE_2D =3D 1,
    VK_IMAGE_TYPE_3D =3D 2,
} VkImageType;
  • VK_IMAGE_TYPE_1D specifies a one-dimensional image.

  • VK_IMAGE_TYPE_2D specifies a two-dimensional image.

  • VK_IMAGE_TYPE_3D specifies a three-dimensional image.

Possible values of VkImageCreateInfo::tilin= g, specifying the tiling arrangement of data elements in an image, are:

typedef enum VkImageTiling {
    VK_IMAGE_TILING_OPTIMAL =3D 0,
    VK_IMAGE_TILING_LINEAR =3D 1,
} VkImageTiling;
  • VK_IMAGE_TILING_OPTIMAL specifies optimal tiling (texels ar= e laid out in an implementation-dependent arrangement, for more optimal memory access).

  • VK_IMAGE_TILING_LINEAR specifies linear tiling (texels are = laid out in memory in row-major order, possibly with some padding on each row).

To query the host access layout of an image subresource, for an image created with linear tiling, call:

void vkGetImageSubresourceLayout(
    VkDevice                                    device,
    VkImage                                     image,
    const VkImageSubresource*             =
      pSubresource,
    VkSubresourceLayout*                        pLayout);
  • device is the logical device that owns the image.

  • image is the image whose layout is being queried.

  • pSubresource is a pointer to a VkImageS= ubresource structure selecting a specific image for the image subresource.

  • pLayout points to a VkSubresourceLayou= t structure in which the layout is returned.

vkGetImageSubresourceLayout is invariant for the lifetime o= f a single image. However, the subresource layout of images in Android hardware buffer external memory is not known until the image has been bound to memory, so calling vkGetImageSubresourceLayout for such an image before i= t has been bound will result in undefined behavior.

Valid Usage
  • image must have been created= with tiling equal to VK_IMAGE_TILING_LINEAR

  • The aspectMask member of pSubresource must only have a single bit set

  • The mipLevel member of pSubresource must be less than the mipLevels specified in VkImageCreateInfo when image was created

  • The arrayLayer member of pSubresource must be less than the arrayLayers specified in VkImageCreateInfo<= /a> when image was created

  • If the format of image is a multi-planar format with two planes, the aspectMask member of pSubresource must be V= K_IMAGE_ASPECT_PLANE_0_BIT or VK_IMAGE_ASPECT_PLANE_1_BIT

  • If the format of image is a multi-planar format with three planes, the aspectMask member of pSubresource must be V= K_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT or VK_IMAGE_ASPECT_PLANE_2_B= IT

  • If image was created with the VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID external memory handle type, then image must be bound to memory.

Valid Usage (Implicit)
  • d= evice must be a valid VkDevi= ce handle

  • im= age must be a valid VkImage<= /code> handle

  • <= code>pSubresource must be a valid = pointer to a valid VkImageSubresource structure

  • = pLayout must be a valid pointer to= a VkSubresourceLayout structure

  • image= must have been created, allocated= , or retrieved from device

The VkImageSubresource structure is defined as:

typedef struct VkImageSubresour=
ce {
    VkImageAspectFlags    aspectMask;
    uint32_t              mipLevel;
    uint32_t              arrayLayer;
} VkImageSubresource;
  • aspectMask is a VkImageAspectFlags = selecting the image aspect.

  • mipLevel selects the mipmap level.

  • arrayLayer selects the array layer.

Valid Usage (Implicit)

Information about the layout of the image subresource is returned in a VkSubresourceLayout structure:

typedef struct VkSubresourceLay=
out {
    VkDeviceSize    offset;
    VkDeviceSize    size;
    VkDeviceSize    rowPitch;
    VkDeviceSize    arrayPitch;
    VkDeviceSize    depthPitch;
} VkSubresourceLayout;
  • offset is the byte offset from the start of the image where= the image subresource begins.

  • size is the size in bytes of the image subresource. size includes any extra memory that is required based on rowPitch.

  • rowPitch describes the number of bytes between each row of = texels in an image.

  • arrayPitch describes the number of bytes between each array= layer of an image.

  • depthPitch describes the number of bytes between each slice= of 3D image.

For images created with linear tiling, rowPitch, arra= yPitch and depthPitch describe the layout of the image subresource in lin= ear memory. For uncompressed formats, rowPitch is the number of bytes betw= een texels with the same x coordinate in adjacent rows (y coordinates differ by one). arrayPitch is the number of bytes between texels with the same= x and y coordinate in adjacent array layers of the image (array layer values differ by one). depthPitch is the number of bytes between texels with the same= x and y coordinate in adjacent slices of a 3D image (z coordinates differ by one). Expressed as an addressing formula, the starting byte of a texel in the image subresource has address:

// (x,y,z,layer) are in texel coordinates
address(x,y,z,layer) =3D layer*arrayPitch + z*depthPitch + y*rowPitch + x*e=
lementSize + offset

For compressed formats, the rowPitch is the number of bytes= between compressed texel blocks in adjacent rows. arrayPitch is the number of bytes between compressed texel blo= cks in adjacent array layers. depthPitch is the number of bytes between compressed texel blo= cks in adjacent slices of a 3D image.

// (x,y,z,layer) are in compressed texel block coordinates
address(x,y,z,layer) =3D layer*arrayPitch + z*depthPitch + y*rowPitch + x*c=
ompressedTexelBlockByteSize + offset;

arrayPitch is undefined for images that were not created as= arrays. depthPitch is defined only for 3D images.

For single-plane color formats, the aspectMask member of VkImageSubresour= ce must be VK_IMAGE_ASPECT_COLOR_BIT. For depth/stencil formats, aspectMask must be either VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT= . On implementations that store depth and stencil aspects separately, queryin= g each of these image subresource layouts will return a different offse= t and size representing the region of memory used for that aspec= t. On implementations that store depth and stencil aspects interleaved, the same offset and size are returned and represent t= he interleaved memory allocation.

For multi-planar formats, the aspectMask member of VkImageSubresource= must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or (for 3-plane formats only) VK_IMAGE_ASPECT_PLANE_2_BIT. Querying each of these image subresource layouts will return a different offset and size representing the region of memory= used for that plane.

To destroy an image, call:

void vkDestroyImage(
    VkDevice                                    device,
    VkImage                                     image,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the image.

  • image is the image to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to image, either directly or= via a VkImageView, must have com= pleted execution

  • If VkAllocationCallbacks were provided when image= was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when image was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device = must be a valid VkDevice han= dle

  • If image= is not VK_NULL_HANDLE, image must be a valid VkImage handle

  • If pAlloca= tor is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • If image is= a valid handle, it must have been create= d, allocated, or retrieved from device

Host Synchronization
  • Host access to image must= be externally synchronized

11.3.1. Image Format Features

Valid usage of a VkImage may be constrained by the image=E2=80=99s format features, defined below. Such constraints are documented in the affected valid usage statement.

11.4. Image Layouts

Images are stored in implementation-dependent opaque layouts in memory. Each layout has limitations on what kinds of operations are supported for image subresources using the layout. At any given time, the data representing an image subresource in memory exists in a particular layout which is determined by the most recent layout transition that was performed on that image subresource. Applications have control over which layout each image subresource uses, an= d can transition an image subresource from = one layout to another. Transitions can happen with an image memo= ry barrier, included as part of a vkCmdPipelineBarrier or a vkCmdWaitEvents command= buffer command (see Image Memory Barriers), or = as part of a subpass dependency within a render pass (see VkSubpassDependency). The image layout is per-image subresource, and separate image subresources of the same image can be in different lay= outs at the same time with one exception - depth and stencil aspects of a given image subresource must always be in the same layout.

Note

Each layout may offer optimal performa= nce for a specific usage of image memory. For example, an image with a layout of VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL may provide optimal performance for use as a color attachment, but be unsupported for use in transfer commands. Applications can transition an image subr= esource from one layout to another in order to achieve optimal performance when the image subresource is used for multiple kinds of operations. After initialization, applications need not use any layout other than the general layout, though this may produce s= uboptimal performance on some implementations.

Upon creation, all image subresources of an image are initially in the s= ame layout, where that layout is selected by the VkImageCreateInfo::initialLayout member. The initialLayout must be ei= ther VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED. If it is VK_IMAGE_LAYOUT_PREINITIALIZED, then the image data <= strong class=3D"purple">can be preinitialized by the host while using this layout, and the transition away from this layout will preserve that data. If it is VK_IMAGE_LAYOUT_UNDEFINED, then the contents of the d= ata are considered to be undefined, and the transition away from this layout is not guaranteed to preserve that data. For either of these initial layouts, any image subresources must be transitioned to another layout before they are accessed by the device.

Host access to image memory is only well-defined for images created with VK_IMAGE_TILING_LINEAR tiling and for image subresources of th= ose images which are currently in either the VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERA= L layout. Calling vkGetImageSubresourceLayout for a = linear image returns a subresource layout mapping that is valid for either of those image layouts.=

The set of image layouts consists of:

typedef enum VkImageLayout {
    VK_IMAGE_LAYOUT_UNDEFINED =3D 0,
    VK_IMAGE_LAYOUT_GENERAL =3D 1,
    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL =3D 2<=
/span>,
    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL =3D 3,
    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL =3D 4,
    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL =3D 5<=
/span>,
    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL =3D 6,
    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL =3D 7,
    VK_IMAGE_LAYOUT_PREINITIALIZED =3D 8,
    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL =3D 1000117000,
    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL =3D 1000117001,
    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR =3D 1000001002<=
/span>,
    VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR =3D 10001110=
00,
    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR =3D VK_I=
MAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR =3D VK_I=
MAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
} VkImageLayout;

The type(s) of device access supported by each layout are:

  • VK_IMAGE_LAYOUT_UNDEFINED does not support device access. This layout must only be used as the initialLayout member of VkImageCreateInfo or VkAttachmentDescription, or = as the oldLayout in an image transition. When transitioning out of this layout, the contents of the memory are not guaranteed to be preserved.

  • VK_IMAGE_LAYOUT_PREINITIALIZED does not support device acce= ss. This layout must only be used as the initialLayout member of VkImageCreateInfo or VkAttachmentDescription, or = as the oldLayout in an image transition. When transitioning out of this layout, the contents of the memory are preserved. This layout is intended to be used as the initial layout for an image whose contents are written by the host, and hence the data can be written to memory immediately, without first executing a layout transition. Currently, VK_IMAGE_LAYOUT_PREINITIALIZED is only useful with VK_IMAGE_TILING_LINEAR images because there is not a standard layout defined for VK_IMAGE_TILING_OPTIMAL images.

  • VK_IMAGE_LAYOUT_GENERAL supports all types of device access= .

  • VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL must only be used as a color or resolve attachment in a VkFramebuffer. This layout is valid only for image subresources of images created with the VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT usage bit enabled.

  • VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL must only be used as a depth/stencil attachment in a VkFramebuffer. This layout is valid only for image subresources of images created with the VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT usage bit enab= led.

  • VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL must only be used as a read-only depth/stencil attachment in a VkFramebuffer and= /or as a read-only image in a shader (which can be read as a sampled image, combined image/sampler and/or input attachment). This layout is valid only for image subresources of images created with the VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT usage bit enab= led. Only image subresources of images created with VK_IMAGE_USAGE_SAMPLED_BIT can be used as a sampled image or combined image/sampler in a shader. Similarly, only image subresources of images created with VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT c= an be used as input attachments.

  • VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:= must only be used as a depth/stencil attachment in a VkFramebuffer, where the depth aspect is read-only, and/or as a read-only image in a shader (which can be read as a sampled im= age, combined image/sampler and/or input attachment) where only the depth aspect is accessed. This layout is valid only for image subresources of images created with the VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT usage bit enab= led. Only image subresources of images created with VK_IMAGE_USAGE_SAMPLED_BIT can be used as a sampled image or combined image/sampler in a shader. Similarly, only image subresources of images created with VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT c= an be used as input attachments.

  • VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:= must only be used as a depth/stencil attachment in a VkFramebuffer, where the stencil aspect is read-only, and/or as a read-only image in a shader (which can be read as a sampled im= age, combined image/sampler and/or input attachment) where only the stencil aspect is accessed. This layout is valid only for image subresources of images created with the VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT usage bit enab= led. Only image subresources of images created with VK_IMAGE_USAGE_SAMPLED_BIT can be used as a sampled image or combined image/sampler in a shader. Similarly, only image subresources of images created with VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT c= an be used as input attachments.

  • VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL must only be used as a read-only image in a shader (which can be= read as a sampled image, combined image/sampler and/or input attachment). This layout is valid only for image subresources of images created with the VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT usage bit enabled.

  • VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL must only be used as a source image of a transfer command (see the definition of VK_PIPELINE_STAGE_TRANSFER_= BIT). This layout is valid only for image subresources of images created with the VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage bit enabled.

  • VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL must only be used as a destination image of a transfer command. This layout is valid only for image subresources of images created with the VK_IMAGE_USAGE_TRANSFER_DST_BIT usage bit enabled.

  • VK_IMAGE_LAYOUT_PRESENT_SRC_KHR mu= st only be used for presenting a presentable image for display. A swapchain=E2=80=99s image must be trans= itioned to this layout before calling vkQueuePresentKHR, and must= be transitioned away from this layout after calling vkAcquireNextImageKHR.

  • VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR is valid only for shared presentable images, and must be used for = any usage the image supports.

The layout of each image subresource is not a state of the image subreso= urce itself, but is rather a property of how the data in memory is organized, an= d thus for each mechanism of accessing an image in the API the application must specify a parameter or structure mem= ber that indicates which image layout the image subresource(s) are considered to be in when the image will be accessed. For transfer commands, this is a parameter to the command (see Clea= r Commands and Copy Commands). For use as a framebuffer attachment, this is a member in the substructures of the VkRenderPassCreateInfo (see Render Pass= ). For use in a descriptor set, this is a member in the VkDescriptorImageInfo structure (see D= escriptor Set Updates). At the time that any command buffer command accessing an image executes on any queue, the layouts of the image subresources that are accessed must all match the layout specified via the API controlling those accesses.

When performing a layout transition on an image subresource, the old lay= out value must either equal the current layou= t of the image subresource (at the time the transition executes), or else be VK_IMAGE_LAYOUT_UNDEFINED (implying that the contents of the image subresource need not be preserved)= . The new layout used in a transition must = not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALI= ZED.

The image layout of each image subresource of a depth/stencil image crea= ted with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT= is dependent on the last sample locations used to render to the image subresource as a depth/stencil attachment, thus applications must provide the same sample locations that were last used to render to the given image subresource whenever a layout transition of the image subresource happens, otherwise the contents of the depth aspect of the image subresource become undefined.

In addition, depth reads from a depth/stencil attachment referring to an image subresource range of a depth/stencil image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT usin= g different sample locations than what have been last used to perform depth writes to the image subresources of the same image subresource range produc= e undefined results.

Similarly, depth writes to a depth/stencil attachment referring to an im= age subresource range of a depth/stencil image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT usin= g different sample locations than what have been last used to perform depth writes to the image subresources of the same image subresource range make the contents of the depth aspect of those image subresources undefined.

11.5. Image Views

Image objects are not directly accessed by pipeline shaders for reading = or writing image data. Instead, image views representing contiguous ranges of the image subresources and containing additional metadata are used for that purpose. Views must be created on images of compat= ible types, and must represent a valid subset of image subresources.

Image views are represented by VkImageView handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkImageView)

The types of image views that can be c= reated are:

typedef enum VkImageViewType {
    VK_IMAGE_VIEW_TYPE_1D =3D 0,
    VK_IMAGE_VIEW_TYPE_2D =3D 1,
    VK_IMAGE_VIEW_TYPE_3D =3D 2,
    VK_IMAGE_VIEW_TYPE_CUBE =3D 3,
    VK_IMAGE_VIEW_TYPE_1D_ARRAY =3D 4,
    VK_IMAGE_VIEW_TYPE_2D_ARRAY =3D 5,
    VK_IMAGE_VIEW_TYPE_CUBE_ARRAY =3D 6,
} VkImageViewType;

The exact image view type is partially implicit, based on the image=E2= =80=99s type and sample count, as well as the view creation parameters as described in the image view compatibility table for vkCreateImageView. This table also shows which SPIR-V OpTypeImage Dim and Arrayed parameters correspond to each image view type.

To create an image view, call:

VkResult vkCreateI=
mageView(
    VkDevice                                    device,
    const VkImageViewCreateInfo*          =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkImageView*                                pView);
  • device is the logical device that creates the image view.

  • pCreateInfo is a pointer to an instance of the VkImageViewCreateInfo structure containing parameters to be us= ed to create the image view.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pView points to a VkImageView handle in wh= ich the resulting image view object is returned.

Some of the image creation parameters are inherited by the view. In particular, image view creation inherits the implicit parameter usage specifying the allowed usages of the image view that, by default, takes the value of the corresponding usage parameter specified in VkImageCreateInfo at image creation time. This implicit parameter can be overriden = by chaining a VkImageViewUsageCreateInfo structure throug= h the pNext member to VkImageViewCreateInfo as described later in this section.

The remaining parameters are contained in the pCreateInfo.<= /p>

Valid Usage (Implicit)
  • device must be a valid VkDevice = handle

  • pCreat= eInfo must be a valid pointer to a= valid VkImageViewCreateInfo structure

  • If pAll= ocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocatio= nCallbacks structure

  • pView= must be a valid pointer to a VkIma= geView handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkImageViewCreateInfo structure is defined as:

typedef struct VkImageViewCreat=
eInfo {
    VkStructureType            sType;
    const void*                pNext;
    VkImageViewCreateFlags     flags;
    VkImage                    image;
    VkImageViewType            viewType;
    VkFormat                   format;
    VkComponentMapping         components;
    VkImageSubresourceRange    subresourceRange;
} VkImageViewCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • image is a VkImage on which the view will be c= reated.

  • viewType is an VkImageViewType value s= pecifying the type of the image view.

  • format is a VkFormat describing the format an= d type used to interpret data elements in the image.

  • components is a VkComponentMapping = specifies a remapping of color components (or of depth or stencil components after they have been converted into color components).

  • subresourceRange is a VkImageSubre= sourceRange selecting the set of mipmap levels and array layers to be accessible to the view.

If image was created with the VK_IMAGE_CREATE_MUTABLE= _FORMAT_BIT flag, and if the format of the image is not multi-planar, format can be different from= the image=E2=80=99s format, but if image was created without the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag and they are not equal they must be compa= tible. Image format compatibility is defined in the Format Compatibility Classes section. Views of compatible formats will have the same mapping between texel coordinates and memory locations irrespective of the format, w= ith only the interpretation of the bit pattern changing.

Note

Values intended to be used with one view format may not be exactly preserved when written or read through a different format. For example, an integer value that happens to have the bit pattern of a floating point denorm or NaN may be flush= ed or canonicalized when written or read through a view with a floating point format. Similarly, a value written through a signed normalized format that has a bi= t pattern exactly equal to -2b may be changed to -2b + 1 as described in Conversion from Normalized Fixed-Point to Floating-Point.

If image was created with the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag, fo= rmat must be compatible with the imag= e=E2=80=99s format as described above, or must be an uncompressed format in which case it must be size-compatible with the image=E2=80=99s format, as defined for copying data between images In this case the resulting image view=E2=80=99s texel dimensions equal the dim= ensions of the selected mip level divided by the compressed texel block size and rounded up.

If the image view is to be used with a sampler which supports sampler Y=E2=80=99CBCR con= version, an identically defined object of type VkSamplerYcbcrConvers= ion to that used to create the sampler must be passed to vkCreateImageView in a VkSamplerYcbcrConversionInfo added to the= pNext chain of VkImageViewCreateInfo.

If the image has a multi-planar format and subresourceRange.aspectMask is VK_IMAGE_ASPECT_COLOR_BIT, format must be identical to the image format, and the sampler to be used with the image view <= strong class=3D"purple">must enable sampler Y=E2=80=99CBCR conversion.

If image was created with the VK_IMAGE_CREATE_MUTABLE= _FORMAT_BIT and the image has a multi-planar format, and if subresourceRange.aspectMask is VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT, format must be compatible with the corresponding plane of the image, and the sampler to be used with the image view must not enable sampler Y=E2=80=99CBCR conversion. The width and height of the single-plane image vi= ew must be derived from the multi-planar image=E2=80=99s dimensions in the manner list= ed for plane compatibility for the plane.<= /p>

Any view of an image plane will have the same mapping between texel coordinates and memory locations as used by the channels of the color aspect, subject to the formulae relating texel coordinates to lower-resolution planes as described in Chr= oma Reconstruction. That is, if an R or B plane has a reduced resolution relative to the G plan= e of the multi-planar image, the image view operates using the (upla= ne, vplane) unnormalized coordinates of the reduced-resolut= ion plane, and these coordinates access the same memory locations as the (ucolor<= /sub>, vcolor) unnormalized coordinates of the color aspect fo= r which chroma reconstruction operations operate on the same (uplane, = vplane) or (iplane, jplane) coordinates.

Table 15. Image and image view parameter compatibi= lity requirements
Dim, Arrayed, MS Image parameters View parameters

imageType =3D ci.imageType
width =3D ci.extent.width
height =3D ci.extent.height
depth =3D ci.extent.depth
arrayLayers =3D ci.arrayLayers
samples =3D ci.samples
flags =3D ci.flags
where ci is the VkImageCreateInfo used to create= image.

baseArrayLayer, layerCount, and levelCount are members of the subresourceRange member.

1D,= 0, 0

imageType =3D VK_IMAGE_TYPE_1D
width =E2=89=A5 1
height =3D 1
depth =3D 1
arrayLayers =E2=89=A5 1
samples =3D 1

viewType =3D VK_IMAGE_VIEW_TYPE_1D
baseArrayLayer =E2=89=A5 0
layerCount =3D 1

1D,= 1, 0

imageType =3D VK_IMAGE_TYPE_1D
width =E2=89=A5 1
height =3D 1
depth =3D 1
arrayLayers =E2=89=A5 1
samples =3D 1

viewType =3D VK_IMAGE_VIEW_TYPE_1D_ARRAY
baseArrayLayer =E2=89=A5 0
layerCount =E2=89=A5 1

2D,= 0, 0

imageType =3D VK_IMAGE_TYPE_2D
width =E2=89=A5 1
height =E2=89=A5 1
depth =3D 1
arrayLayers =E2=89=A5 1
samples =3D 1

viewType =3D VK_IMAGE_VIEW_TYPE_2D
baseArrayLayer =E2=89=A5 0
layerCount =3D 1

2D,= 1, 0

imageType =3D VK_IMAGE_TYPE_2D
width =E2=89=A5 1
height =E2=89=A5 1
depth =3D 1
arrayLayers =E2=89=A5 1
samples =3D 1

viewType =3D VK_IMAGE_VIEW_TYPE_2D_ARRAY
baseArrayLayer =E2=89=A5 0
layerCount =E2=89=A5 1

2D,= 0, 1

imageType =3D VK_IMAGE_TYPE_2D
width =E2=89=A5 1
height =E2=89=A5 1
depth =3D 1
arrayLayers =E2=89=A5 1
samples > 1

viewType =3D VK_IMAGE_VIEW_TYPE_2D
baseArrayLayer =E2=89=A5 0
layerCount =3D 1

2D,= 1, 1

imageType =3D VK_IMAGE_TYPE_2D
width =E2=89=A5 1
height =E2=89=A5 1
depth =3D 1
arrayLayers =E2=89=A5 1
samples > 1

viewType =3D VK_IMAGE_VIEW_TYPE_2D_ARRAY
baseArrayLayer =E2=89=A5 0
layerCount =E2=89=A5 1

CUB= E, 0, 0

imageType =3D VK_IMAGE_TYPE_2D
width =E2=89=A5 1
height =3D width
depth =3D 1
arrayLayers =E2=89=A5 6
samples =3D 1
flags includes VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT

viewType =3D VK_IMAGE_VIEW_TYPE_CUBE
baseArrayLayer =E2=89=A5 0
layerCount =3D 6

CUB= E, 1, 0

imageType =3D VK_IMAGE_TYPE_2D
width =E2=89=A5 1
height =3D width
depth =3D 1
N =E2=89=A5 1
arrayLayers =E2=89=A5 6 =C3=97 N
samples =3D 1
flags includes VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT

viewType =3D VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
baseArrayLayer =E2=89=A5 0
layerCount =3D 6 =C3=97 N, N =E2=89=A5 1

=

3D,= 0, 0

imageType =3D VK_IMAGE_TYPE_3D
width =E2=89=A5 1
height =E2=89=A5 1
depth =E2=89=A5 1
arrayLayers =3D 1
samples =3D 1

viewType =3D VK_IMAGE_VIEW_TYPE_3D
baseArrayLayer =3D 0
layerCount =3D 1

3D,= 0, 0

imageType =3D VK_IMAGE_TYPE_3D
width =E2=89=A5 1
height =E2=89=A5 1
depth =E2=89=A5 1
arrayLayers =3D 1
samples =3D 1
flags includes VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT
flags does not include VK_IMAGE_CREATE_SPARSE_BINDING_BI= T, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, and VK_I= MAGE_CREATE_SPARSE_ALIASED_BIT

viewType =3D VK_IMAGE_VIEW_TYPE_2D
levelCount =3D 1
baseArrayLayer =E2=89=A5 0
layerCount =3D 1

3D,= 0, 0

imageType =3D VK_IMAGE_TYPE_3D
width =E2=89=A5 1
height =E2=89=A5 1
depth =E2=89=A5 1
arrayLayers =3D 1
samples =3D 1
flags includes VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT
flags does not include VK_IMAGE_CREATE_SPARSE_BINDING_BI= T, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, and VK_I= MAGE_CREATE_SPARSE_ALIASED_BIT

viewType =3D VK_IMAGE_VIEW_TYPE_2D_ARRAY
levelCount =3D 1
baseArrayLayer =E2=89=A5 0
layerCount =E2=89=A5 1

Valid Usage
  • If image was not created with VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT then viewType= must not be VK_IMAGE_VIEW_TYPE_CUBE or VK_IMAGE_VIEW_TYPE_CUBE_AR= RAY

  • If the image cubemap arrays feature is not enabled, viewType must not be VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If image was created with VK_IMAGE_TYPE_3D but wi= thout VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT set then viewTyp= e must not be VK_IMAGE_VIEW_TYPE_2D or VK_IMAGE_VIEW_TYPE_2D_ARRAY

  • If image was created with VK_IMAGE_TILING_LINEAR, format must be format that h= as at least one supported feature bit present in the value of VkFormatProperties::linearTilingFeatures returned= by vkGetPhysicalDeviceFormatProperties with the same value of format

  • image must have been created= with a usage value containing at least one of VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT

  • If image was created with VK_IMAGE_TILING_LINEAR = and usage contains VK_IMAGE_USAGE_SAMPLED_BIT, = format must be supported for sampled images, as = specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT flag in VkFormatProperties::linearTilingFeatures returned= by vkGetPhysicalDeviceFormatProperties with the same value of format

  • If image was created with VK_IMAGE_TILING_LINEAR = and usage contains VK_IMAGE_USAGE_STORAGE_BIT, = format must be supported for storage images, as = specified by the VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT flag in VkFormatProperties::linearTilingFeatures returned= by vkGetPhysicalDeviceFormatProperties with the same value of format

  • If image was created with VK_IMAGE_TILING_LINEAR = and usage contains VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format must be supported for= color attachments, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::linearTilingFeatures returned= by vkGetPhysicalDeviceFormatProperties with the same value of format

  • If image was created with VK_IMAGE_TILING_LINEAR = and usage contains VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_B= IT, format must be supported for= depth/stencil attachments, as specified by the VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in VkFormatProperties::linearTilingFeatures = returned by vkGetPhysicalDeviceFormatProperties with the same value of format

  • If image was created with VK_IMAGE_TILING_OPTIMAL= and format is not VK_FORMAT_UNDEFINED, format must be format that has at least one supported feature bit present in the value of VkFormatProperties::optimalTilingFeatures retu= rned by vkGetPhysicalDeviceFormatProperties with the same value of format

  • If image was created with VK_IMAGE_TILING_OPTIMAL= , and format is not VK_FORMAT_UNDEFINED, and usag= e contains VK_IMAGE_USAGE_SAMPLED_BIT, format must be supported for sampled images, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT flag in VkFormatProperties::optimalTilingFeatures returne= d by vkGetPhysicalDeviceFormatProperties with the same value of format

  • If image was created with VK_IMAGE_TILING_OPTIMAL= , and format is not VK_FORMAT_UNDEFINED, and usag= e contains VK_IMAGE_USAGE_STORAGE_BIT, format must be supported for storage images, as specified by the VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT flag in VkFormatProperties::optimalTilingFeatures returne= d by vkGetPhysicalDeviceFormatProperties with the same value of format

  • If image was created with VK_IMAGE_TILING_OPTIMAL= , and format is not VK_FORMAT_UNDEFINED, and usag= e contains VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format must be supported for color attachments, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::optimalTilingFeatures returne= d by vkGetPhysicalDeviceFormatProperties with the same value of format

  • If image was created with VK_IMAGE_TILING_OPTIMAL= , and format is not VK_FORMAT_UNDEFINED, and usag= e contains VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, format must be supported for depth/stencil attachments, as specified by the VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in VkFormatProperties::optimalTilingFeatures returne= d by vkGetPhysicalDeviceFormatProperties with the same value of format

  • subresourceRange.baseMipLevel must be less than the mipLevels specified in VkImageCreateInfo when image was created

  • If subresourceRange.levelCount is not VK_REMAINING_MIP_LEVELS, subresourceR= ange.baseMipLevel + subresourceRange.levelCount must be less than or equal to the mipLevels specified in VkImageCreateInf= o when image was created

  • If image is not a 3D image created with VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT set, or viewType= is not VK_IMAGE_VIEW_TYPE_2D or VK_IMAGE_VIEW_TYPE_2D_ARRAY= , subresourceRange::baseArrayLayer must be less than the arrayLayers specified in VkImageCreateInfo<= /a> when image was created

  • If subresourceRange::layerCount is not VK_REMAINING_ARRAY_LAYERS, image is not a 3D imag= e created with VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT set, or viewType is not VK_IMAGE_VIEW_TYPE_2D or VK_IMAGE_VIEW_TYPE_2D_ARRAY, subresourceRange::layerCount must be non-zero and subresourceRange::baseArrayLayer +=20 subresourceRange::layerCount must be less than or equal to the arrayLayers specified in VkImageCreateI= nfo when image was created

  • If image is a 3D image created with VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT set, and viewTyp= e is VK_IMAGE_VIEW_TYPE_2D or VK_IMAGE_VIEW_TYPE_2D_ARRAY, subresourceRange::baseArrayLayer must be less than the extent.depth specified in VkImageCreateInfo= when image was created

  • If subresourceRange::layerCount is not VK_REMAINING_ARRAY_LAYERS, image is a 3D image cr= eated with VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT set, and viewTyp= e is VK_IMAGE_VIEW_TYPE_2D or VK_IMAGE_VIEW_TYPE_2D_ARRAY, subresourceRange::layerCount must be non-zero and subresourceRange::baseArrayLayer +=20 subresourceRange::layerCount must be less than or equal to the extent.depth specified in VkImageCreate= Info when image was created

  • If image was created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, format <= strong class=3D"purple">must be compatible with the format used to create image, = as defined in Format Compatibility Classes

  • If image was created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, but without the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag, and if the format of the image is not a multi-planar format, format must be compatible wi= th the format used to create image, as defined in Format Compatibility Classes

  • If image was created with the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag, fo= rmat must be compatible with, or must be an uncompressed format that is size-compatible with, the format used to create image.

  • If image was created with the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag, the levelCount and layerCount members of subres= ourceRange must both be 1.

  • If a VkImageFormatListCreateInfoKHR structure was included in = the pNext chain of the VkImageCreateInfo struct used = when creating image and the viewFormatCount field of VkImageFormatListCreateInfoKHR is not zero then format must be one of the formats in VkImageFormatListCreateInfoKHR::pViewFormats.

  • If image was created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, if the format of the image is a multi-planar format, and if subresourceRange.aspectMask is one of VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT, then format must be compatible with the VkFormat for the plane of the image format indicated by subresourceRange.aspectMask, as defined in Compatible formats of planes of multi-p= lanar formats

  • If image was not created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, or if the format of the image is a multi-planar format and if subresourceRange.aspectMask is VK_IMAGE_ASPECT_COLOR_BIT, format must be identical to = the format used to create image

  • If the pNext chain contains an instance of VkSamplerYcbcrConversionInfo with a conversion value other than VK_NULL_HANDLE, all members of components must have the value VK_COMPONENT_SWIZZLE_IDENTITY.

  • If image is non-sparse then it must be bound completely and contiguously to a single VkDeviceMemory object

  • subresourceRange and viewType must be compatible with the image, as described in the compatibility table

  • If image has an external format:

    • format must be VK_F= ORMAT_UNDEFINED

    • The pNext chain must cont= ain an instance of VkSamplerYcbcrConversionInfo with a conversion object created with the same external format as image

    • All members of components must be VK_COMPONENT_SWIZZLE_IDENTITY

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_IMAGE_VI= EW_CREATE_INFO

  • Each pNext member of any structure (including this one) in the pNext chain must be either NULL = or a pointer to a valid instance of VkImageView= UsageCreateInfo or VkSamplerYcbcrConversi= onInfo

  • Each sType<= /code> member in the pNext chain must= be unique

  • flags<= /code> must be 0

  • image must be a valid VkImage= handle

  • viewT= ype must be a valid VkImageViewType value

  • format<= /code> must be a valid VkFormat= value

  • com= ponents must be a valid VkCo= mponentMapping structure

  • subresourceRange must be a vali= d VkImageSubresourceRange structure

typedef VkFlags VkImageViewCreateFlags;

VkImageViewCreateFlags is a bitmask type for setting a mask= , but is currently reserved for future use.

The set of usages for the created image view ca= n be restricted compared to the parent image=E2=80=99s usage flags by chaining a VkImageViewUsageCreateInfo structure through the pNext member to VkImageViewCreateInfo.

The VkImageViewUsageCreateInfo structure is defined as:

typedef struct VkImageViewUsage=
CreateInfo {
    VkStructureType      sType;
    const void*          pNext;
    VkImageUsageFlags    usage;
} VkImageViewUsageCreateInfo;

or the equivalent

typedef VkImageViewUsageCreateInfo VkImageViewUsageCreateInfoK=
HR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • usage is a bitmask describing the allowed usages of the ima= ge view. See VkImageUsageFlagBits for a description of the= supported bits.

When this structure is chained to VkImageViewCreateInfo the usage field overrides the implicit usage paramete= r inherited from image creation time and its value is used instead for the purposes of determining the valid usage conditions of VkImageVie= wCreateInfo.

Valid Usage
  • usage must not include any s= et bits that were not set in the usage member of the VkImageCreateInfo s= tructure used to create the image this image view is created from.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_IMA= GE_VIEW_USAGE_CREATE_INFO

  • usa= ge must be a valid combination of = VkImageUsageFlagBits values

  • usage must not be 0

The VkImageSubresourceRange structure is defined as:

typedef struct VkImageSubresour=
ceRange {
    VkImageAspectFlags    aspectMask;
    uint32_t              baseMipLevel;
    uint32_t              levelCount;
    uint32_t              baseArrayLayer;
    uint32_t              layerCount;
} VkImageSubresourceRange;
  • aspectMask is a bitmask of VkImageAs= pectFlagBits specifying which aspect(s) of the image are included in the view.

  • baseMipLevel is the first mipmap level accessible to the vi= ew.

  • levelCount is the number of mipmap levels (starting from baseMipLevel) accessible to the view.

  • baseArrayLayer is the first array layer accessible to the v= iew.

  • layerCount is the number of array layers (starting from baseArrayLayer) accessible to the view.

The number of mipmap levels and array layers mu= st be a subset of the image subresources in the image. If an application wants to use all mip levels or layers in an image after the baseMipLevel or baseArrayLayer, it can set levelCount and layerCount to the special values VK_REMAINING_MIP_LE= VELS and VK_REMAINING_ARRAY_LAYERS without knowing the exact number of = mip levels or layers.

For cube and cube array image views, the layers of the image view starti= ng at baseArrayLayer correspond to faces in the order +X, -X, +Y,= -Y, +Z, -Z. For cube arrays, each set of six sequential layers is a single cube, so the number of cube maps in a cube map array view is layerCount= / 6, and image array layer (baseArrayLayer + i) is face index (i mod 6) of cube i / 6. If the number of layers in the view, whether set explicitly in layerCount or implied by VK_REMAINING_ARRAY_LAYERS, is not a multiple of 6, behavior when indexing the last cube is undefined.

aspectMask must be only <= code>VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT= if format is a color, depth-only or stencil-only format, respectively, except if format is a multi-planar format. If using a depth/stencil format with both depth and stencil components, aspectMask must include at l= east one of VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BI= T, and can include both.

When the VkImageSubresourceRange structure is used to selec= t a subset of the slices of a 3D image=E2=80=99s mip level in order to create a 2D or = 2D array image view of a 3D image created with VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, baseArrayLayer<= /code> and layerCount specify the first slice index and the number of sli= ces to include in the created image view. Such an image view can be used as a frame= buffer attachment that refers only to the specified range of slices of the selected mip level. However, any layout transitions performed on such an attachment view during a render pass instance still apply to the entire subresource referenced which includes all the slices of the selected mip level.

When using an imageView of a depth/stencil image to populate a descripto= r set (e.g. for sampling in the shader, or for use as an input attachment), the aspectMask must only inc= lude one bit and selects whether the imageView is used for depth reads (i.e. using a floating-point sampler or input attachment in the shader) or stencil reads (i.e. using an unsigned integer sampler or input attachment in the shader). When an imageView of a depth/stencil image is used as a depth/stencil framebuffer attachment, the aspectMask is ignored and both dep= th and stencil image subresources are used.

The components member is of type VkComp= onentMapping, and describes a remapping from components of the image to components of the vector returned by shader image instructions. This remapping must be identity for stora= ge image descriptors, input attachment descriptors, framebuffer attachments, and any VkImageView used with a combi= ned image sampler that enables sampler Y=E2=80=99CBCR conversion.

When creating a VkImageView, if = sampler Y=E2=80=99CBCR conversion is enabled in the sampl= er, the aspectMask of a subresourceRange used by the VkImageView must be VK_IMAGE_ASPECT_COLOR_BIT.

When creating a VkImageView, if sampler Y=E2=80=99CBCR conversion is not enabled in the sampler and the image format is multi-planar, the image must have been created with V= K_IMAGE_CREATE_MUTABLE_FORMAT_BIT, and the aspectMask of the VkImageView=E2=80=99s <= code>subresourceRange must be VK_IMAGE_ASPECT_PLANE_0_BIT= , VK_IMAGE_ASPECT_PLANE_1_BIT or VK_IMAGE_ASPECT_PLANE_2_B= IT.

Valid Usage
  • If levelCount is not VK_REMAINING_MIP_LEVELS, it = must be greater than 0

  • If layerCount is not VK_REMAINING_ARRAY_LAYERS, i= t must be greater than 0

  • If aspectMask includes VK_IMAGE_ASPECT_COLOR_BIT,= then it must not include any of VK_IMAGE_AS= PECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT, or VK_IMAGE_ASPECT_PLANE_2_= BIT

Valid Usage (Implicit)
  • a= spectMask must be a valid combinat= ion of VkImageAspectFlagBits values

  • <= code>aspectMask must not be = 0

Bits which can be set in an aspect mas= k to specify aspects of an image for purposes such as identifying a subresource, are:

typedef enum VkImageAspectFlagB=
its {
    VK_IMAGE_ASPECT_COLOR_BIT =3D 0x00000001,
    VK_IMAGE_ASPECT_DEPTH_BIT =3D 0x00000002,
    VK_IMAGE_ASPECT_STENCIL_BIT =3D 0x00000004,
    VK_IMAGE_ASPECT_METADATA_BIT =3D 0x00000008,
    VK_IMAGE_ASPECT_PLANE_0_BIT =3D 0x00000010,
    VK_IMAGE_ASPECT_PLANE_1_BIT =3D 0x00000020,
    VK_IMAGE_ASPECT_PLANE_2_BIT =3D 0x00000040,
    VK_IMAGE_ASPECT_PLANE_0_BIT_KHR =3D VK_IMAGE_ASPECT_PLANE_0_BIT,
    VK_IMAGE_ASPECT_PLANE_1_BIT_KHR =3D VK_IMAGE_ASPECT_PLANE_1_BIT,
    VK_IMAGE_ASPECT_PLANE_2_BIT_KHR =3D VK_IMAGE_ASPECT_PLANE_2_BIT,
} VkImageAspectFlagBits;
  • VK_IMAGE_ASPECT_COLOR_BIT specifies the color aspect.

  • VK_IMAGE_ASPECT_DEPTH_BIT specifies the depth aspect.

  • VK_IMAGE_ASPECT_STENCIL_BIT specifies the stencil aspect.

  • VK_IMAGE_ASPECT_METADATA_BIT specifies the metadata aspect,= used for sparse sparse resource operations.

typedef VkFlags VkImageAspectFlags;

VkImageAspectFlags is a bitmask type for setting a mask of = zero or more VkImageAspectFlagBits.

The VkComponentMapping structure is defined as:

typedef struct VkComponentMappi=
ng {
    VkComponentSwizzle    r;
    VkComponentSwizzle    g;
    VkComponentSwizzle    b;
    VkComponentSwizzle    a;
} VkComponentMapping;
  • r is a VkComponentSwizzle specifyin= g the component value placed in the R component of the output vector.

  • g is a VkComponentSwizzle specifyin= g the component value placed in the G component of the output vector.

  • b is a VkComponentSwizzle specifyin= g the component value placed in the B component of the output vector.

  • a is a VkComponentSwizzle specifyin= g the component value placed in the A component of the output vector.

Valid Usage (Implicit)

Possible values of the members of VkComponentMapping= , specifying the component values placed in each component of the output vector, are:

typedef enum VkComponentSwizzle=
 {
    VK_COMPONENT_SWIZZLE_IDENTITY =3D 0,
    VK_COMPONENT_SWIZZLE_ZERO =3D 1,
    VK_COMPONENT_SWIZZLE_ONE =3D 2,
    VK_COMPONENT_SWIZZLE_R =3D 3,
    VK_COMPONENT_SWIZZLE_G =3D 4,
    VK_COMPONENT_SWIZZLE_B =3D 5,
    VK_COMPONENT_SWIZZLE_A =3D 6,
} VkComponentSwizzle;
  • VK_COMPONENT_SWIZZLE_IDENTITY specifies that the component = is set to the identity swizzle.

  • VK_COMPONENT_SWIZZLE_ZERO specifies that the component is s= et to zero.

  • VK_COMPONENT_SWIZZLE_ONE specifies that the component is se= t to either 1 or 1.0, depending on whether the type of the image view format is integer or floating-point respectively, as determined by the Format Definition section for each VkFormat.

  • VK_COMPONENT_SWIZZLE_R specifies that the component is set = to the value of the R component of the image.

  • VK_COMPONENT_SWIZZLE_G specifies that the component is set = to the value of the G component of the image.

  • VK_COMPONENT_SWIZZLE_B specifies that the component is set = to the value of the B component of the image.

  • VK_COMPONENT_SWIZZLE_A specifies that the component is set = to the value of the A component of the image.

Setting the identity swizzle on a component is equivalent to setting the identity mapping on that component. That is:

Table 16. Component Mappings Equivalent To V= K_COMPONENT_SWIZZLE_IDENTITY
Component Identity Mapping

components.r

VK_COMPONENT_SWIZZLE_R

components.g

VK_COMPONENT_SWIZZLE_G

components.b

VK_COMPONENT_SWIZZLE_B

components.a

VK_COMPONENT_SWIZZLE_A

To destroy an image view, call:

void vkDestroyImageView(
    VkDevice                                    device,
    VkImageView                                 imageView,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the image view.<= /p>

  • imageView is the image view to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to imageView must have completed execution

  • If VkAllocationCallbacks were provided when imageView was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when imageView= was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • If imag= eView is not VK_NULL_HANDLE, imageView must be a valid VkImageView handle

  • If pAl= locator is not NULL, pAllocator must be a valid pointer to a valid VkAllocati= onCallbacks structure

  • If imageVi= ew is a valid handle, it must have= been created, allocated, or retrieved from device

Host Synchronization
  • Host access to imageView must be externally synchronized

11.5.1. Image View Format F= eatures

Valid usage of a VkImageView m= ay be constrained by the image view=E2=80=99s format features, defined below. Such constraints are documented in the affected valid usage statement.

11.6. Resource Memory Association

Resources are initially created as virtual allocations with no = backing memory. Device memory is allocated separately (see Device Memory= ) and then associated with the resource. This association is done differently for sparse and non-sparse resources.

Resources created with any of the sparse creation flags are considered sparse resources. Resources created without these flags are non-sparse. The details on resource memory association for sparse resources is describe= d in Sparse Resources.

Non-sparse resources must be bound com= pletely and contiguously to a single VkDeviceMemory object before the resource is passed as a param= eter to any of the following operations:

  • creating image or buffer views

  • updating descriptor sets

  • recording commands in a command buffer

Once bound, the memory binding is immutable for the lifetime of the resource.

In a logical device representing more than one physical device, buffer a= nd image resources exist on all physical devices but = can be bound to memory differently on each. Each such replicated resource is an instance of the resource. For sparse resources, each instance can b= e bound to memory arbitrarily differently. For non-sparse resources, each instance can either be bound to the local or a peer instance of the memory, or for images can be bound to rectangular regions from the local and/or peer instances. When a resource is used in a descriptor set, each physical device interpret= s the descriptor according to its own instance=E2=80=99s binding to memory.

Note

There are no new copy commands to transfer data between physical devices= . Instead, an application can create a reso= urce with a peer mapping and use it as the source or destination of a transfer command executed by a single physical device to copy the data from one physical device to another.

To determine the memory requirements for a buffer resource, call:

void vkGetBufferMemoryRequirements(
    VkDevice                                    device,
    VkBuffer                                    buffer,
    VkMemoryRequirements*                       pMemoryRequirements);
  • device is the logical device that owns the buffer.

  • buffer is the buffer to query.

  • pMemoryRequirements points to an instance of the VkMemoryRequirements structure in which the memor= y requirements of the buffer object are returned.

Valid Usage (Implicit)
  • device must be a valid VkDe= vice handle

  • buffer must be a valid VkBu= ffer handle

  • pMemoryRequirements must be a valid pointer to a VkMemoryRequirements structure

  • bu= ffer must have been created, alloc= ated, or retrieved from device

To determine the memory requirements for an image resource which is not created with the VK_IMAGE_CREATE_DISJOINT_BIT flag set, call:<= /p>

void vkGetImageMemoryRequirements(
    VkDevice                                    device,
    VkImage                                     image,
    VkMemoryRequirements*                       pMemoryRequirements);
  • device is the logical device that owns the image.

  • image is the image to query.

  • pMemoryRequirements points to an instance of the VkMemoryRequirements structure in which the memor= y requirements of the image object are returned.

Valid Usage
  • image must not have been cre= ated with the VK_IMAGE_CREATE_DISJOINT_BIT flag set

Valid Usage (Implicit)
  • = device must be a valid VkDev= ice handle

  • i= mage must be a valid VkImage= handle

  • pMemoryRequirements must be a valid pointer to a VkMemoryRequirements structure

  • imag= e must have been created, allocate= d, or retrieved from device

The VkMemoryRequirements structure is defined as:

typedef struct VkMemoryRequirem=
ents {
    VkDeviceSize    size;
    VkDeviceSize    alignment;
    uint32_t        memoryTypeBits;
} VkMemoryRequirements;
  • size is the size, in bytes, of the memory allocation required for the resource.

  • alignment is the alignment, in bytes, of the offset within = the allocation required for the resource.

  • memoryTypeBits is a bitmask and contains one bit set for ev= ery supported memory type for the resource. Bit i is set if and only if the memory type i in = the VkPhysicalDeviceMemoryProperties structure for the physical de= vice is supported for the resource.

The precise size of images that will be bound to external Android hardwa= re buffer memory is unknown until the memory has been imported or allocated, s= o calling vkGetImageMemoryRequirements with= such an image before it has been bound to memory will result in undefined behavior. When importing Android hardware buffer memory, the allocationSize can be determined by calling vkGet= AndroidHardwareBufferPropertiesANDROID. When allocating new memory for an image that can be exported to an Android hardware buffer, the memory=E2=80=99s allocationSize must be zero; the actual size will be determined by the dedicated image=E2=80=99s parameters. After the memory has been allocated, the amount of space allocated from the memory=E2=80=99s heap can be obtained by = getting the image=E2=80=99s memory requirements or by calling vkGetAndroidHardwar= eBufferPropertiesANDROID with the Android hardware buffer exported from the memory.

The implementation guarantees certain properties about the memory requirements returned by vkGetBufferMemoryRe= quirements and vkGetImageMemoryRequirements:

  • The memoryTypeBits member always contains at least one bit = set.

  • If buffer is a VkBuffer not created with the VK_BUFFER_CREATE_SPARSE_BINDING_BIT bit set, or if image= is a VkImage that was created with a VK_IMAGE_TILING_LINEAR= value in the tiling member of the VkImageCreateInfo structure passed to vkCreateImage, then the memoryTypeBi= ts member always contains at least one bit set corresponding to a VkMemoryType with a propertyFlags that has both t= he VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit and the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit set. In other words, mappable coherent memory can always be attached to these objects.

  • If buffer was created with VkExternalMemoryBufferCreateInfo::handleTypes set to 0 or image was created with VkExternalMemoryImageCreateInfo::handleTypes set to 0, the memoryTypeBits member always contains at least one bit set corresponding to a VkMemoryType with a propertyFlags that has the VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit set.

  • The memoryTypeBits member is identical for all VkBuff= er objects created with the same value for the flags and us= age members in the VkBufferCreateInfo structure and the handleTypes member of the VkExternalMemoryBufferCreateInfo stru= cture passed to vkCreateBuffer. Further, if usage1 and usage2 of type VkBufferUsageFlags are such that the bits set in usage2 are a subset of the bits = set in usage1, and they have the same flags and VkExternalMemoryBufferCreateInfo::handleTypes, then the bits set in memoryTypeBits returned for usage1<= /code> must be a subset of the bits set in memoryTypeBits returned for usage2, for all values of flags.

  • The alignment member is a power of two.

  • The alignment member is identical for all VkBuffer objects created with the same combination of values for the usage and flags members in the VkBufferCreateInfo structure= passed to vkCreateBuffer.

  • The alignment member satisfies the buffer descriptor offset alignment requirements associated with the VkBuffer=E2=80=99s = usage:

    • If usage included VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, alignment must be an integer multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment.

    • If usage included VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT<= /code>, alignment must be an integer= multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment<= /code>.

    • If usage included VK_BUFFER_USAGE_STORAGE_BUFFER_BIT<= /code>, alignment must be an integer= multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment<= /code>.

  • For images created with a color format, the memoryTypeBits = member is identical for all VkImage objects created with the same combination of values for the tiling member, the VK_IMAGE_CREATE_SPARSE_BINDING_BIT bit of the flags member, the VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT bit of the flags member, handleTypes member of VkExter= nalMemoryImageCreateInfo, and the VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT of the u= sage member in the VkImageCreateInfo structure passed to vkCreateImage.

  • For images created with a depth/stencil format, the memoryTypeBits= member is identical for all VkImage objects created with the s= ame combination of values for the format member, the tiling<= /code> member, the VK_IMAGE_CREATE_SPARSE_BINDING_BIT bit of the flags member, the VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT bit of the flags member, handleTypes member of VkExter= nalMemoryImageCreateInfo, and the VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT of the u= sage member in the VkImageCreateInfo structure passed to vkCreateImage.

  • If the memory requirements are for a VkImage, the memoryTypeBits member must n= ot refer to a VkMemoryType with a propertyFlags that has the VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set if the vkGetImageMemoryRequirements::image= did not have VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT bit set in the u= sage member of the VkImageCreateInfo structure passed to vkCreateImage.

  • If the memory requirements are for a VkBuffer, the memoryTypeBits member must n= ot refer to a VkMemoryType with a propertyFlags that has the VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set.

    Note

    The implication of this requirement is that lazily allocated memory is disallowed for buffers in all cases.

  • The size member is identical for all VkBuffer = objects created with the same combination of creation parameters specified in VkBufferCreateInfo and its pNext chain.

  • The size member is identical for all VkImage o= bjects created with the same combination of creation parameters specified in VkImageCreateInfo and its pNext chain.

    Note

    This, however, does not imply that they interpret the contents of the bo= und memory identically with each other. That additional guarantee, however, can b= e explicitly requested using VK_IMAGE_CREATE_ALIAS_BIT.

To determine the memory requirements for a buffer resource, call:

void vkGetBufferMemoryRequirements2(
    VkDevice                                    device,
    const VkBufferMemoryRequirementsInfo2*=
      pInfo,
    VkMemoryRequirements2*                      pMemoryRequirements);

or the equivalent command

void vkGetBufferMemoryRequirements2KHR(
    VkDevice                                    device,
    const VkBufferMemoryRequirementsInfo2*=
      pInfo,
    VkMemoryRequirements2*                      pMemoryRequirements);
  • device is the logical device that owns the buffer.

  • pInfo is a pointer to an instance of the VkBufferMemoryRequirementsInfo2 structure containing parameter= s required for the memory requirements query.

  • pMemoryRequirements points to an instance of the VkMemoryRequirements2 structure in which the mem= ory requirements of the buffer object are returned.

Valid Usage (Implicit)
  • device must be a valid VkD= evice handle

  • pInfo must be a valid pointer to = a valid VkBufferMemoryRequirementsInfo2 structure

  • pMemoryRequirements must be a valid pointer to a VkMemoryRequirements2 structure<= /p>

The VkBufferMemoryRequirementsInfo2 structure is defined as= :

typedef struct VkBufferMemoryRe=
quirementsInfo2 {
    VkStructureType    sType;
    const void*        pNext;
    VkBuffer           buffer;
} VkBufferMemoryRequirementsInfo2;

or the equivalent

typedef VkBufferMemoryRequirementsInfo2 VkBufferMemoryRequirem=
entsInfo2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • buffer is the buffer to query.

Valid Usage (Implicit)
  • sT= ype must be VK_STRUCTURE_TYP= E_BUFFER_MEMORY_REQUIREMENTS_INFO_2

  • pN= ext must be NULL

  • buffer must be a valid Vk= Buffer handle

To determine the memory requirements for an image resource, call:

void vkGetImageMemoryRequirements2(
    VkDevice                                    device,
    const VkImageMemoryRequirementsInfo2* =
      pInfo,
    VkMemoryRequirements2*                      pMemoryRequirements);

or the equivalent command

void vkGetImageMemoryRequirements2KHR(
    VkDevice                                    device,
    const VkImageMemoryRequirementsInfo2* =
      pInfo,
    VkMemoryRequirements2*                      pMemoryRequirements);
  • device is the logical device that owns the image.

  • pInfo is a pointer to an instance of the VkImageMemoryRequirementsInfo2 structure containing parameters required for the memory requirements query.

  • pMemoryRequirements points to an instance of the VkMemoryRequirements2 structure in which the mem= ory requirements of the image object are returned.

Valid Usage (Implicit)
  • device must be a valid VkDe= vice handle

  • = pInfo must be a valid pointer to a= valid VkImageMemoryRequirementsInfo2 structure

  • pMemoryRequirements must be a valid pointer to a VkMemoryRequirements2 structure

The VkImageMemoryRequirementsInfo2 structure is defined as:=

typedef struct VkImageMemoryReq=
uirementsInfo2 {
    VkStructureType    sType;
    const void*        pNext;
    VkImage            image;
} VkImageMemoryRequirementsInfo2;

or the equivalent

typedef VkImageMemoryRequirementsInfo2 VkImageMemoryRequiremen=
tsInfo2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • image is the image to query.

Valid Usage
Valid Usage (Implicit)
  • sTy= pe must be VK_STRUCTURE_TYPE= _IMAGE_MEMORY_REQUIREMENTS_INFO_2

  • pNe= xt must be NULL or a = pointer to a valid instance of VkImageP= laneMemoryRequirementsInfo

  • image must be a valid VkIma= ge handle

To determine the memory requirements for a plane of a disjoint image, ad= d a VkImagePlaneMemoryRequirementsInfo to the pNext c= hain of the VkImageMemoryRequirementsInfo2 structure.

The VkImagePlaneMemoryRequirementsInfo structure is defined= as:

typedef struct VkImagePlaneMemo=
ryRequirementsInfo {
    VkStructureType          sType;
    const void*              pNext;
    VkImageAspectFlagBits    planeAspect;
} VkImagePlaneMemoryRequirementsInfo;

or the equivalent

typedef VkImagePlaneMemoryRequirementsInfo VkImagePlaneMemoryR=
equirementsInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • planeAspect is the aspect corresponding to the image plane = to query.

Valid Usage
  • planeAspect must be an aspec= t that exists in the format; that is, for a two-plane image planeAspect mus= t be VK_IMAGE_ASPECT_PLANE_0_BIT or VK_IMAGE_ASPECT_PLANE_1_B= IT, and for a three-plane image planeAspect must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= or VK_IMAGE_ASPECT_PLANE_2_BIT

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_= TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO

  • = planeAspect must be a v= alid VkImageAspectFlagBits value

The VkMemoryRequirements2 structure is defined as:

typedef struct VkMemoryRequirem=
ents2 {
    VkStructureType         sType;
    void*                   pNext;
    VkMemoryRequirements    memoryRequirements;
} VkMemoryRequirements2;

or the equivalent

typedef VkMemoryRequirements2 VkMemoryRequirements2KHR;=
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memoryRequirements is a structure of type VkMemoryRequirements describing the memory requir= ements of the resource.

Valid Usage (Implicit)

To determine the dedicated allocation requirements of a buffer or image resource, add a VkMemoryDedicatedRequirement= s structure to the pNext chain of the VkMemoryRequirements= 2 structure passed as the pMemoryRequirements parameter of vkGetBufferMemoryRequir= ements2 or vkGetImageMemoryRequirements2.

The VkMemoryDedicatedRequirements structure is defined as:<= /p>

typedef struct VkMemoryDedicate=
dRequirements {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           prefersDedicatedAllocation;
    VkBool32           requiresDedicatedAllocation;
} VkMemoryDedicatedRequirements;

or the equivalent

typedef VkMemoryDedicatedRequirements VkMemoryDedicatedRequire=
mentsKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • prefersDedicatedAllocation specifies that the implementatio= n would prefer a dedicated allocation for this resource. The application is still free to suballocate the resource but it may get better performance if a dedicated allocation is used.

  • requiresDedicatedAllocation specifies that a dedicated allo= cation is required for this resource.

When the implementation sets requiresDedicatedAllocation to VK_TRUE, it must also set prefersDedicatedAllocation to VK_TRUE.

If the VkMemoryDedicatedRequirements structure is included = in the pNext chain of the VkMemoryRequirements= 2 structure passed as the pMemoryRequirements parameter of a vkGetBufferMemoryRequirements2 call, requiresDedicatedAl= location may be VK_TRUE under one of = the following conditions:

  • The pNext chain of VkBufferCreateInfo for the = call to vkCreateBuffer used to create the buffer being queried contain= ed an instance of VkExternalMemoryBufferCreateInfo, and any of th= e handle types specified in VkExternalMemoryBufferCreateInfo::handleTypes req= uires dedicated allocation, as reported by vkGetPhysicalDeviceExternalBuf= ferProperties in VkExternalBufferProperties::externalMemoryProperties::externalMemoryFeatures, the requiresDedicatedAllocation field will be set to VK_TRUE.

In all other cases, requiresDedicatedAllocation must be set to VK_FALSE by the implementation whenever a VkMemoryDedicatedRequirements structure is included in the pNext chain of the VkMemoryRequirements2 structure passed to a call = to vkGetBufferMemoryRequirements2.

If the VkMemoryDedicatedRequirements structure is included = in the pNext chain of the VkMemoryRequirements2 structur= e passed as the pMemoryRequirements parameter of a vkGetBufferMemoryRequirements2 call and VK_BUFFER_CREATE_SPARSE_BINDING_BIT was set in VkBufferCreateInfo::flags when buffer was created then the implementation must set both prefer= sDedicatedAllocation and requiresDedicatedAllocation to VK_FALSE.

If the VkMemoryDedicatedRequirements structure is included = in the pNext chain of the VkMemoryRequirements2 structur= e passed as the pMemoryRequirements parameter of a vkGetImageMemoryRequi= rements2 call, requiresDedicatedAllocation may= be VK_TRUE under one of the following conditions:

  • The pNext chain of VkImageCreateInfo for the c= all to vkCreateImage used to create the image being queried contained= an instance of VkExternalMemoryImageCreateInfo, and any of the ha= ndle types specified in VkExternalMemoryImageCreateInfo::handleTypes requ= ires dedicated allocation, as reported by vkGetPhysicalDeviceImageFormatPr= operties2 in VkExternalImageFormatProperties::externalMemoryPropertie= s::externalMemoryFeatures, the requiresDedicatedAllocation field will be set to VK_TRUE.

In all other cases, requiresDedicatedAllocation must be set to VK_FALSE by the implementation whenever a VkMemoryDedicatedRequirements structure is included in the pNext chain of the VkMemoryRequirements2 structure passed to a call = to vkGetImageMemoryRequirements2.

If the VkMemoryDedicatedRequirements structure is included = in the pNext chain of the VkMemoryRequirements2 structur= e passed as the pMemoryRequirements parameter of a vkGetImageMemoryRequi= rements2 call and VK_IMAGE_CREATE_SPARSE_BINDING_BIT was set in VkImageCreateInfo::flags when image = was created then the implementation must set both prefer= sDedicatedAllocation and requiresDedicatedAllocation to VK_FALSE.

Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= MEMORY_DEDICATED_REQUIREMENTS

To attach memory to a buffer object, call:

VkResult vkBindBuf=
ferMemory(
    VkDevice                                    device,
    VkBuffer                                    buffer,
    VkDeviceMemory                              memory,
    VkDeviceSize                                memoryOffset);
  • device is the logical device that owns the buffer and memor= y.

  • buffer is the buffer to be attached to memory.

  • memory is a VkDeviceMemory object descr= ibing the device memory to attach.

  • memoryOffset is the start offset of the region of mem= ory which is to be bound to the buffer. The number of bytes returned in the VkMemoryRequirements::size member in memory= , starting from memoryOffset bytes, will be bound to the specified buffer= .

vkBindBufferMemory is equivalent to passing the same parame= ters through VkBindBufferMemoryInfo to vkBindBufferMemory2.

Valid Usage
  • buffer must not already be b= acked by a memory object

  • buffer must not have been cr= eated with any sparse memory binding flags

  • memoryOffset must be less th= an the size of memory

  • memory must have been alloca= ted using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer

  • memoryOffset must be an inte= ger multiple of the alignment member of the VkMemoryRequirements structure returned from a c= all to vkGetBufferMemoryRequirements with buffer

  • The size member of the VkMemoryRequirements struc= ture returned from a call to vkGetBufferMemoryRequirements with buffer must be less than or = equal to the size of memory minus memoryOffset

  • If buffer requires a dedicated allocation(as reported by vkGetBufferMemoryRequirements2 in VkMemoryDedicatedRequirements::requiresD= edicatedAllocation for buffer), memory must have been created with VkMemoryDedicatedAllocateInfo::buf= fer equal to buffer

  • If the VkMemoryAllocateInfo provided when memory = was allocated included an instance of VkMemoryDe= dicatedAllocateInfo in its pNext chain, and VkMemoryDedicatedAllocateInfo::buf= fer was not VK_NULL_HANDLE, then buffer must equal VkMemoryDedicatedAllocateInfo::buf= fer, and memoryOffset must be zero.

  • If buffer was created with the VK_BUFFER_CREATE_PROTECTED_BIT = bit set, the buffer must be bound to a memory= object allocated with a memory type that reports VK_MEMORY_PROPERTY_PROTECTED_BIT

  • If buffer was created with the VK_BUFFER_CREATE_PROTECTED_BIT = bit not set, the buffer must not be bound to = a memory object created with a memory type that reports VK_MEMORY_PROPERTY_PROTECTED_BIT

  • If buffer was created with VkDedicatedAllocationBufferCreateI= nfoNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAlloc= ateInfoNV::buffer equal to a buffer handle created with identical creation parameters to buffer and memoryOffset must be zer= o

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • buffer must be a valid VkBuffer= handle

  • memory must be a valid VkDeviceMemory<= /code> handle

  • buffer= must have been created, allocated, or re= trieved from device

  • memory= must have been created, allocated, or re= trieved from device

Host Synchronization
  • Host access to buffer must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

To attach memory to buffer objects for one or more buffers at a time, ca= ll:

VkResult vkBindBuf=
ferMemory2(
    VkDevice                                    device,
    uint32_t                                    bindInfoCount,
    const VkBindBufferMemoryInfo*         =
      pBindInfos);

or the equivalent command

VkResult vkBindBuf=
ferMemory2KHR(
    VkDevice                                    device,
    uint32_t                                    bindInfoCount,
    const VkBindBufferMemoryInfo*         =
      pBindInfos);
  • device is the logical device that owns the buffers and memo= ry.

  • bindInfoCount is the number of elements in pBindInfos= .

  • pBindInfos is a pointer to an array of structures of type VkBindBufferMemoryInfo, describing buffers and = memory to bind.

On some implementations, it may be mor= e efficient to batch memory bindings into a single command.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pBind= Infos must be a valid pointer to a= n array of bindInfoCount valid VkBindBufferMemoryInfo structures

  • = bindInfoCount must be greater than= 0

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

VkBindBufferMemoryInfo contains members corresponding to th= e parameters of vkBindBufferMemory.

The VkBindBufferMemoryInfo structure is defined as:

typedef struct VkBindBufferMemo=
ryInfo {
    VkStructureType    sType;
    const void*        pNext;
    VkBuffer           buffer;
    VkDeviceMemory     memory;
    VkDeviceSize       memoryOffset;
} VkBindBufferMemoryInfo;

or the equivalent

typedef VkBindBufferMemoryInfo VkBindBufferMemoryInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • buffer is the buffer to be attached to memory.

  • memory is a VkDeviceMemory object descr= ibing the device memory to attach.

  • memoryOffset is the start offset of the region of mem= ory which is to be bound to the buffer. The number of bytes returned in the VkMemoryRequirements::size member in memory= , starting from memoryOffset bytes, will be bound to the specified buffer= .

Valid Usage
  • buffer must not already be b= acked by a memory object

  • buffer must not have been cr= eated with any sparse memory binding flags

  • memoryOffset must be less th= an the size of memory

  • memory must have been alloca= ted using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer

  • memoryOffset must be an inte= ger multiple of the alignment member of the VkMemoryRequirements structure returned from a c= all to vkGetBufferMemoryRequirements with buffer

  • The size member of the VkMemoryRequirements struc= ture returned from a call to vkGetBufferMemoryRequirements with buffer must be less than or = equal to the size of memory minus memoryOffset

  • If buffer requires a dedicated allocation(as reported by vkGetBufferMemoryRequirements2 in VkMemoryDedicatedRequirements::requiresD= edicatedAllocation for buffer), memory must have been created with VkMemoryDedicatedAllocateInfo::buf= fer equal to buffer and memoryOffset must be zer= o

  • If the VkMemoryAllocateInfo provided when memory = was allocated included an instance of VkMemoryDe= dicatedAllocateInfo in its pNext chain, and VkMemoryDedicatedAllocateInfo::buf= fer was not VK_NULL_HANDLE, then buffer must equal VkMemoryDedicatedAllocateInfo::buf= fer and memoryOffset must be zero.

  • If buffer was created with VkDedicatedAllocationBufferCreateI= nfoNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAlloc= ateInfoNV::buffer equal to buffer and memoryOffset = must be zero

  • If the pNext chain includes VkBindBufferMemoryDeviceGroupInfo, a= ll instances of memory specified by VkBindBufferMemoryDeviceGroupInfo::<= code>pDeviceIndices must have been allocated

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_BIND_BU= FFER_MEMORY_INFO

  • pNext must be NULL or a pointer = to a valid instance of VkBindBufferMemor= yDeviceGroupInfo

  • buffer= must be a valid VkBuffer handle

  • memory= must be a valid VkDeviceMem= ory handle

  • Both of bu= ffer, and memory must= have been created, allocated, or retrieved from the same VkDevice

typedef struct VkBindBufferMemo=
ryDeviceGroupInfo {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           deviceIndexCount;
    const uint32_t*    pDeviceIndices;
} VkBindBufferMemoryDeviceGroupInfo;

or the equivalent

typedef VkBindBufferMemoryDeviceGroupInfo VkBindBufferMemoryDe=
viceGroupInfoKHR;

If the pNext list of VkBindBufferMe= moryInfo includes a VkBindBufferMemoryDeviceGroupInfo structure, then that structu= re determines how memory is bound to buffers across multiple devices in a device group.

The VkBindBufferMemoryDeviceGroupInfo structure is defined = as:

  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • deviceIndexCount is the number of elements in pDeviceIndices.

  • pDeviceIndices is a pointer to an array of device indices.<= /p>

If deviceIndexCount is greater than zero, then on device in= dex i the buffer is attached to the instance of memory on the physic= al device with device index pDeviceIndices[i].

If deviceIndexCount is zero and memory comes f= rom a memory heap with the VK_MEMORY_HEAP_MULTI_INSTANCE_BIT bit set, then it is= as if pDeviceIndices contains consecutive indices from zero to the n= umber of physical devices in the logical device, minus one. In other words, by default each physical device attaches to its own instanc= e of memory.

If deviceIndexCount is zero and memory comes f= rom a memory heap without the VK_MEMORY_HEAP_MULTI_INSTANCE_BIT bit set, then it= is as if pDeviceIndices contains an array of zeros. In other words, by default each physical device attaches to instance zero.<= /p>

Valid Usage
Valid Usage (Implicit)
  • = sType must be VK_STRUCTURE_T= YPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO

  • If deviceIndexCount is not 0, pDevic= eIndices must be a valid pointer t= o an array of deviceIndexCount uint32_t values

To attach memory to a VkImage object created without the VK_IMAGE_CREATE_DISJOINT_BIT set, call:

VkResult vkBindIma=
geMemory(
    VkDevice                                    device,
    VkImage                                     image,
    VkDeviceMemory                              memory,
    VkDeviceSize                                memoryOffset);
  • device is the logical device that owns the image and memory= .

  • image is the image.

  • memory is the VkDeviceMemory object des= cribing the device memory to attach.

  • memoryOffset is the start offset of the region of mem= ory which is to be bound to the image. The number of bytes returned in the VkMemoryRequirements::size member in memory= , starting from memoryOffset bytes, will be bound to the specified image.=

vkBindImageMemory is equivalent to passing the same paramet= ers through VkBindImageMemoryInfo to vkB= indImageMemory2.

Valid Usage
  • image must not have been cre= ated with the VK_IMAGE_CREATE_DISJOINT_BIT set.

  • image must not already be ba= cked by a memory object

  • image must not have been cre= ated with any sparse memory binding flags

  • memoryOffset must be less th= an the size of memory

  • memory must have been alloca= ted using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image

  • memoryOffset must be an inte= ger multiple of the alignment member of the VkMemoryRequirements structure returned from a c= all to vkGetImageMemoryRequirements with image

  • The size member of the VkMemoryRequirements struc= ture returned from a call to vkGetImageMemoryRequirements with image must be less than or e= qual to the size of memory minus memoryOffset

  • If image requires a dedicated allocation (as reported by vkGetImageMemoryRequirements2 in VkMemoryDedicatedRequirements::requiresD= edicatedAllocation for image), memory must have been created with VkMemoryDedicatedAllocateInfo::ima= ge equal to image

  • If the VkMemoryAllocateInfo provided when memory = was allocated included an instance of VkMemoryDe= dicatedAllocateInfo in its pNext chain, and VkMemoryDedicatedAllocateInfo::ima= ge was not VK_NULL_HANDLE, then image must equal VkMemoryDedicatedAllocateInfo::ima= ge and memoryOffset must be zero.

  • If image was created with the VK_IMAGE_CREATE_PROTECTED_BIT bi= t set, the image must be bound to a memory = object allocated with a memory type that reports VK_MEMORY_PROPERTY_PROTECTED_BIT

  • If image was created with the VK_IMAGE_CREATE_PROTECTED_BIT bi= t not set, the image must not be bound to a= memory object created with a memory type that reports VK_MEMORY_PROPERTY_PROTECTED_BIT

  • If image was created with VkDedicatedAllocationImageCreateInf= oNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAlloc= ateInfoNV::image equal to an image handle created with identical creation parameters to image and memoryOffset must be zer= o

Valid Usage (Implicit)
  • device must be a valid VkDevice = handle

  • image= must be a valid VkImage han= dle

  • memory must be a valid VkDeviceMemory handle

  • image must have been created, allocated, or retri= eved from device

  • memory = must have been created, allocated, or ret= rieved from device

Host Synchronization
  • Host access to image must= be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

To attach memory to image objects for one or more images at a time, call= :

VkResult vkBindIma=
geMemory2(
    VkDevice                                    device,
    uint32_t                                    bindInfoCount,
    const VkBindImageMemoryInfo*          =
      pBindInfos);

or the equivalent command

VkResult vkBindIma=
geMemory2KHR(
    VkDevice                                    device,
    uint32_t                                    bindInfoCount,
    const VkBindImageMemoryInfo*          =
      pBindInfos);
  • device is the logical device that owns the images and memor= y.

  • bindInfoCount is the number of elements in pBindInfos= .

  • pBindInfos is a pointer to an array of structures of type VkBindImageMemoryInfo, describing images and mem= ory to bind.

On some implementations, it may be mor= e efficient to batch memory bindings into a single command.

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • pBindI= nfos must be a valid pointer to an= array of bindInfoCount valid VkBindImageMemoryInfo structures

  • b= indInfoCount must be greater than = 0

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

VkBindImageMemoryInfo contains members corresponding to the= parameters of vkBindImageMemory.

The VkBindImageMemoryInfo structure is defined as:

typedef struct VkBindImageMemor=
yInfo {
    VkStructureType    sType;
    const void*        pNext;
    VkImage            image;
    VkDeviceMemory     memory;
    VkDeviceSize       memoryOffset;
} VkBindImageMemoryInfo;

or the equivalent

typedef VkBindImageMemoryInfo VkBindImageMemoryInfoKHR;=
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • image is the image to be attached to memory.

  • memory is a VkDeviceMemory object descr= ibing the device memory to attach.

  • memoryOffset is the start offset of the region of mem= ory which is to be bound to the image. The number of bytes returned in the VkMemoryRequirements::size member in memory= , starting from memoryOffset bytes, will be bound to the specified image.=

Valid Usage
Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_BIND_IMA= GE_MEMORY_INFO

  • Each pNext member of any structure (including this one) in the pNext chain must be either NULL = or a pointer to a valid instance of VkBin= dImageMemoryDeviceGroupInfo, VkBindI= mageMemorySwapchainInfoKHR, or VkBindImageP= laneMemoryInfo

  • Each sType<= /code> member in the pNext chain must= be unique

  • image must be a valid VkImage= handle

  • Both of ima= ge, and memory that are valid handles must have been created, allocated, or retrieved from the s= ame VkDevice

typedef struct VkBindImageMemor=
yDeviceGroupInfo {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           deviceIndexCount;
    const uint32_t*    pDeviceIndices;
    uint32_t           splitInstanceBindRegionCount;
    const VkRect2D*    pSplitInstanceBindR=
egions;
} VkBindImageMemoryDeviceGroupInfo;

or the equivalent

typedef VkBindImageMemoryDeviceGroupInfo VkBindImageMemoryDevi=
ceGroupInfoKHR;

If the pNext list of VkBindImageMemo= ryInfo includes a VkBindImageMemoryDeviceGroupInfo structure, then that structur= e determines how memory is bound to images across multiple devices in a devic= e group.

The VkBindImageMemoryDeviceGroupInfo structure is defined a= s:

  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • deviceIndexCount is the number of elements in pDeviceIndices.

  • pDeviceIndices is a pointer to an array of device indices.<= /p>

  • splitInstanceBindRegionCount is the number of elements in pSplitInstanceBindRegions.

  • pSplitInstanceBindRegions is a pointer to an array of recta= ngles describing which regions of the image are attached to each instance of memory.

If deviceIndexCount is greater than zero, then on device in= dex i image is attached to the instance of the memory on the physica= l device with device index pDeviceIndices[i].

Let N be the number of physical devices in the= logical device. If splitInstanceBindRegionCount is greater than zero, then pSplitInstanceBindRegions is an array of N<= sup>2 rectangles, where the image region specified by the rectangle at element i= *N+j in resource instance i is bound to the memory instan= ce j. The blocks of the memory that are bound to each sparse image block region use an offset in memory, relative to memoryOffset, computed as= if the whole image were being bound to a contiguous range of memory. In other words, horizontally adjacent image blocks use consecutive blocks o= f memory, vertically adjacent image blocks are separated by the number of bytes per block multiplied by the width in blocks of image, an= d the block at (0,0) corresponds to memory starting at = memoryOffset.

If splitInstanceBindRegionCount and deviceIndexCount<= /code> are zero and the memory comes from a memory heap with the VK_MEMORY_HEAP_MULTI_INSTANCE_BIT bit set, then it is as if pDeviceIndices contains consecutive indices from zero to the n= umber of physical devices in the logical device, minus one. In other words, by default each physical device attaches to its own instanc= e of the memory.

If splitInstanceBindRegionCount and deviceIndexCount<= /code> are zero and the memory comes from a memory heap without the VK_MEMORY_HEAP_MULTI_INSTANCE_BIT bit set, then it is as if pDeviceIndices contains an array of zeros. In other words, by default each physical device attaches to instance zero.<= /p>

Valid Usage
  • <= /a> At least one of deviceIndexCount and splitInstanceBindRegionCount must be zero.

  • <= /a> deviceIndexCount must either= be zero or equal to the number of physical devices in the logical device

  • All elements of pDeviceIndices must be valid device indices.

  • splitInstanceBindRegionCount must either be zero or equal to the number of physical devices in the logical device squared

  • Elements of pSplitInstanceBindRegions that correspond to the s= ame instance of an image must not overlap.

  • The offset.x member of any element of pSplitInstanceBindRegions must be a multiple of the sparse image block width (VkSparseImageFormatProperties::imageGranularity.width) of all non-metadata aspects of the image

  • The offset.y member of any element of pSplitInstanceBindRegions must be a multiple of the sparse image block height (VkSparseImageFormatProperties::imageGranularity.height<= /code>) of all non-metadata aspects of the image

  • The extent.width member of any element of pSplitInstanceBindRegions must either be a multiple of the sparse image block width of all non-metadata aspects of the image, or else extent.width + offset.x = must equal the width of the image subresource

  • The extent.height member of any element of pSplitInstanceBindRegions must either be a multiple of the sparse image block height of all non-metadata aspects of the image, or else extent.height
    offset.y must equal the widt= h of the image subresource

Valid Usage (Implicit)
  • s= Type must be VK_STRUCTURE_TY= PE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO

  • If deviceIndexCount is not 0, pDevice= Indices must be a valid pointer to= an array of deviceIndexCount uint32_t values

  • If splitInstanceBindRegionCount is not = 0, pSplitInstanceBindRegions m= ust be a valid pointer to an array of splitInstanceBindRegio= nCount VkRect2D structures

If the pNext chain of VkBindImageMem= oryInfo includes a VkBindImageMemorySwapchainInfoKHR structure, then that structu= re includes a swapchain handle and image index indicating that the image will be bound to memory from that swapchain.

The VkBindImageMemorySwapchainInfoKHR structure is defined = as:

typedef struct VkBindImageMemor=
ySwapchainInfoKHR {
    VkStructureType    sType;
    const void*        pNext;
    VkSwapchainKHR     swapchain;
    uint32_t           imageIndex;
} VkBindImageMemorySwapchainInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • swapchain is VK_NULL_HANDLE or a swapch= ain handle.

  • imageIndex is an image index within swapchain.=

If swapchain is not NULL, the swapchain<= /code> and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.

Memory can be bound to a swapchain and= use the pDeviceIndices or pSplitInstanceBindRegions members of VkBindImageMemoryDeviceGroupInfo.

Valid Usage
  • imageIndex must be less than= the number of images in swapchain

Valid Usage (Implicit)
Host Synchronization
  • Host access to swapchain must be externally synchronized

The VkBindImagePlaneMemoryInfo structure is defined as:

typedef struct VkBindImagePlane=
MemoryInfo {
    VkStructureType          sType;
    const void*              pNext;
    VkImageAspectFlagBits    planeAspect;
} VkBindImagePlaneMemoryInfo;

or the equivalent

typedef VkBindImagePlaneMemoryInfo VkBindImagePlaneMemoryInfoK=
HR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • planeAspect is the aspect of the disjoint image plane to bi= nd.

Valid Usage
  • planeAspect must be a single= valid plane aspect for the image format (that is, planeAspect must be VK_IMAGE_ASPECT_PLANE_0_BIT or VK_IMAGE_ASPECT_PLANE_1_B= IT for =E2=80=9C_2PLANE=E2=80=9D formats and planeAspect must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT for =E2=80=9C_3PLANE= =E2=80=9D formats)

  • A single call to vkBindImageMemory2 must bind all or none of the planes of an image (i.e. bindings to all planes of an image must be made in a single vkBindImageMemory2 call), as separ= ate bindings

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_BIN= D_IMAGE_PLANE_MEMORY_INFO

  • planeAspect must be a valid VkImageAspectFlagBits value

Buffer-Image Granularity

There is an implementation-dependent limit, bufferImageGranularity= , which specifies a page-like granularity at which linear and non-linear resources must be placed in adjacent memo= ry locations to avoid aliasing. Two resources which do not satisfy this granularity requirement are said to alias. bufferImageGranularity is specified in bytes, and must be a power of two. Implementations which do not impose a granularity restriction may report a bufferImageGranularity value of one.

Note

Despite its name, bufferImageGranularity is really a granul= arity between =E2=80=9Clinear=E2=80=9D and =E2=80=9Cnon-linear=E2=80=9D resources= .

Given resourceA at the lower memory offset and resourceB at the higher memory offset in the same VkDeviceMemory object, where one res= ource is linear and the other is non-linear (as defined in the Glossary), and the following:

resourceA.end       =
=3D resourceA.memoryOffset + resourceA.size - 1
resourceA.endPage   =3D resourceA.end & ~(bufferImageGranularity-1)
resourceB.start     =3D resourceB.memoryOffset
resourceB.startPage =3D resourceB.start & ~(bufferImageGranularity-1)

The following property must hold:

resourceA.endPage &l=
t; resourceB.startPage

That is, the end of the first resource (A) and the beginning of the seco= nd resource (B) must be on separate =E2=80= =9Cpages=E2=80=9D of size bufferImageGranularity. bufferImageGranularity may b= e different than the physical page size of the memory heap. This restriction is only needed when a linear resource and a non-linear resource are adjacent in memory and will be used simultaneously. The memory ranges of adjacent resources can be closer than bufferImageGranularity, provided they meet the alignment= requirement for the objects in question.

Sparse block size in bytes and sparse image and buffer memory alignments must all be multiples of the buffer= ImageGranularity. Therefore, memory bound to sparse resources naturally satisfies the bufferImageGranularity.

11.7. Resource Sharing Mode

Buffer and image objects are created with a sharing mode contro= lling how they can be accessed from queues. The supported sharing modes are:

typedef enum VkSharingMode {
    VK_SHARING_MODE_EXCLUSIVE =3D 0,
    VK_SHARING_MODE_CONCURRENT =3D 1,
} VkSharingMode;
  • VK_SHARING_MODE_EXCLUSIVE specifies that access to any rang= e or image subresource of the object will be exclusive to a single queue family at a time.

  • VK_SHARING_MODE_CONCURRENT specifies that concurrent access= to any range or image subresource of the object from multiple queue families is supported.

Note

VK_SHARING_MODE_CONCURRENT may result in lower performance access to the buffer or image than VK_SHARING_MODE_EXCLUSIVE.

Ranges of buffers and image subresources of image objects created using VK_SHARING_MODE_EXCLUSIVE must only be accessed by queues in the queue family that has ownership of the resource. Upon creation, such resources are not owned by any queue family; ownership is implicitly acquired upon first use within a queue. Once a resource using VK_SHARING_MODE_EXCLUSIVE is owned by so= me queue family, the application must perform a queue family ownership transfer to mak= e the memory contents of a range or image subresource accessible to a different queue family.

Note

Images still require a layout transition fr= om VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALI= ZED before being used on the first queue.

A queue family can take ownership of a= n image subresource or buffer range of a resource created with VK_SHARING_MODE_EXCLUSIVE, without = an ownership transfer, in the same way as for a resource that was just created= ; however, taking ownership in this way has the effect that the contents of the image subresource or buffer range are undefined.

Ranges of buffers and image subresources of image objects created using VK_SHARING_MODE_CONCURRENT must only be accessed by queues from the queue families specified through the queueFamilyIndexCount and pQueueFamilyIndices members of the corresponding create info structures.

11.7.1. External Resource Sharing

Resources should only be accessed in t= he Vulkan instance that has exclusive ownership of their underlying memory. Only one Vulkan instance has exclusive ownership of a resource=E2=80=99s un= derlying memory at a given time, regardless of whether the resource was created usin= g VK_SHARING_MODE_EXCLUSIVE or VK_SHARING_MODE_CONCURRENT<= /code>. Applications can transfer ownership of a resource=E2=80=99s underlying memo= ry only if the memory has been imported from or exported to another instance or external API using external memory handles. The semantics for transferring ownership outside of the instance are simila= r to those used for transferring ownership of VK_SHARING_MODE_EXCLUSIVE= resources between queues, and is also accomplished using VkBufferMemoryBarrier or V= kImageMemoryBarrier operations. Applications must

  1. Release exclusive ownership from the source instance or API.

  2. Ensure the release operation has completed using semaphores or fences.

  3. Acquire exclusive ownership in the destination instance or API

Unlike queue ownership transfers, the destination instance or API is not specified explicitly when releasing ownership, nor is the source instance o= r API specified when acquiring ownership. Instead, the image or memory barrier=E2=80=99s dstQueueFamilyIndex or srcQueueFamilyIndex parameters are set to the reserved queue f= amily index VK_QUEUE_FAMILY_EXTERNAL or VK_QUEUE_FAMILY_FOREIGN_EXT to represent the external destination or source respectively.

Binding a resource to a memory object shared between multiple Vulkan instances or other APIs does not change the ownership of the underlying memory. The first entity to access the resource implicitly acquires ownership. Accessing a resource backed by memory that is owned by a particular instanc= e or API has the same semantics as accessing a VK_SHARING_MODE_EXCLUSIV= E resource, with one exception: Implementations must= ensure layout transitions performed on one member of a set of identical subresources of identical images that alias the same range of an underlying memory object affect the layout of all the subresources in the set.

As a corollary, writes to any image subresources in such a set must not make the contents of memory used by other subresources in the set undefined= . An application can define the content of = a subresource of one image by performing device writes to an identical subresource of another image provided both images are bound to the same region of external memory. Applications may also add resources to su= ch a set after the content of the existing set members has been defined without making the content undefined by creating a new image with the initial layout VK_IMAGE_LAYOUT_UNDEFINED and binding it to the same region of external memory as the existing images.

Note

Because layout transitions apply to all identical images aliasing the sa= me region of external memory, the actual layout of the memory backing a new image as well as an existing image with defined content will not be undefined. Such an image is not usable until it acquires ownership of its memory from the existing owner. Therefore, the layout specified as part of this transition will be the true initial layout of the image. The undefined layout specified when creating it is a placeholder to simplif= y valid usage requirements.

11.8. Memory Aliasing

A range of a VkDeviceMemory allocation is aliased = if it is bound to multiple resources simultaneously, as described below, via vkBindImageMemory, vkBindBufferM= emory, via sparse memory bindings, or by bindin= g the memory to resources in multiple Vulkan instances or external APIs using external memory handle export and import mechanisms.

Consider two resources, resourceA and resourceB, b= ound respectively to memory rangeA and rangeB. Let paddedRangeA and paddedRangeB be, respectively, r= angeA and rangeB aligned to bufferImageGranularity. If the resources are both linear or both non-linear (as defined in the Glossary), then the resources alias = the memory in the intersection of rangeA and rangeB. If one resource is linear and the other is non-linear, then the resources alias the memory in the intersection of paddedRangeA an= d paddedRangeB.

Applications can alias memory, but use= of multiple aliases is subject to several constraints.

Note

Memory aliasing can be useful to reduc= e the total device memory footprint of an application, if some large resources are used for disjoint periods of time.

When an opaque, non-VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT im= age is bound to an aliased range, all image subresources of the image overlap<= /em> the range. When a linear image is bound to an aliased range, the image subresources that (according to the image=E2=80=99s advertised layout) include bytes fro= m the aliased range overlap the range. When a VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT image has sparse i= mage blocks bound to an aliased range, only image subresources including those sparse image blocks overlap the range, and when the memory bound to the image=E2=80=99s mip tail overlaps an aliased range all image subresources i= n the mip tail overlap the range.

Buffers, and linear image subresources in either the VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERA= L layouts, are host-accessible subresources. That is, the host has a well-defined addressing scheme to interpret the contents, and thus the layout of the data in memory can be consistently interpreted across aliases if each of those aliases is a host-accessible subresource. Non-linear images, and linear image subresources in other layouts, are not host-accessible.

If two aliases are both host-accessible, then they interpret the content= s of the memory in consistent ways, and data written to one alias can be read by the other alias.

If two aliases are both images that were created with identical creation parameters, both were created with the VK_IMAGE_CREATE_ALIAS_BIT flag set, and both are bound identically to memory except for VkBindImageMemoryDeviceGroupIn= fo::pDeviceIndices and VkBindImageMemoryDeviceGroupInfo::pSplitInstanceBindRegions, then they interpret the contents of the memory in consistent ways, and data written to one alias can be read by the o= ther alias.

Additionally, if an invididual plane of a multi-planar image and a single-plane image alias the same memory, then they also interpret the contents of the memory in consistent ways under the same conditions, but with the following modifications:

  • Both must have been created with the <= code>VK_IMAGE_CREATE_DISJOINT_BIT flag.

  • The single-plane image must have an VkFormat that is equivalent to that of the multi-planar image=E2=80=99s individual plane.

  • The single-plane image and the individual plane of the multi-planar image must be bound identically to memory except for VkBindImageMemoryDeviceGroupIn= fo::pDeviceIndices and VkBindImageMemoryDeviceGroupInfo::pSplitInstanceBindRegions.

  • The width and height of the single-plane image= are derived from the multi-planar image=E2=80=99s dimensions in the manner listed for plane compatibility for the aliased plane.

  • All other creation parameters must be = identical

Aliases created by binding the same memory to resources in multiple Vulk= an instances or external APIs using external memory handle export and import mechanisms interpret the contents of the memory in consistent ways, and dat= a written to one alias can be read by the o= ther alias.

Otherwise, the aliases interpret the contents of the memory differently,= and writes via one alias make the contents of memory partially or completely undefined to the other alias. If the first alias is a host-accessible subresource, then the bytes affecte= d are those written by the memory operations according to its addressing scheme. If the first alias is not host-accessible, then the bytes affected are thos= e overlapped by the image subresources that were written. If the second alias is a host-accessible subresource, the affected bytes become undefined. If the second alias is a not host-accessible, all sparse image blocks (for sparse partially-resident images) or all image subresources (for non-sparse image and fully resident sparse images) that overlap the affected bytes become undefined.

If any image subresources are made undefined due to writes to an alias, = then each of those image subresources must hav= e its layout transitioned from VK_IMAGE_LAYOUT_UNDEFINED to a valid layout before it is used,= or from VK_IMAGE_LAYOUT_PREINITIALIZED if the memory has been written = by the host. If any sparse blocks of a sparse image have been made undefined, then only the image subresources containing them must be transitioned.

Use of an overlapping range by two aliases must= be separated by a memory dependency using the appropriate access types if at least one of those uses performs writes, whether the aliase= s interpret memory consistently or not. If buffer or image memory barriers are used, the scope of the barrier must contain the entire range and/or set of image subresources that overlap.

If two aliasing image views are used in the same framebuffer, then the render pass must declare the attachments = using the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT, and follow the other rules listed in that section.

Access to resources which alias memory from shaders using variables decorated with Coherent are not automatically coherent with ea= ch other.

Note

Memory recycled via an application suballocator (i.e. without freeing an= d reallocating the memory objects) is not substantially different from memory aliasing. However, a suballocator usually waits on a fence before recycling a region of memory, and signaling a fence involves sufficient implicit dependencies to satisfy all the above requirements.

12. Samplers

VkSampler objects represent the state of an image sampler w= hich is used by the implementation to read image data and apply filtering and other transformations for the shader.

Samplers are represented by VkSampler handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkSampler)

To create a sampler object, call:

VkResult vkCreateS=
ampler(
    VkDevice                                    device,
    const VkSamplerCreateInfo*            =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSampler*                                  pSampler);
Valid Usage (Implicit)
  • device= must be a valid VkDevice ha= ndle

  • pCreateI= nfo must be a valid pointer to a v= alid VkSamplerCreateInfo structure

  • If pAlloc= ator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • pSampler must be a valid pointer to a V= kSampler handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_TOO_MANY_OBJECTS

The VkSamplerCreateInfo structure is defined as:

typedef struct VkSamplerCreateI=
nfo {
    VkStructureType         sType;
    const void*             pNext;
    VkSamplerCreateFlags    flags;
    VkFilter                magFilter;
    VkFilter                minFilter;
    VkSamplerMipmapMode     mipmapMode;
    VkSamplerAddressMode    addressModeU;
    VkSamplerAddressMode    addressModeV;
    VkSamplerAddressMode    addressModeW;
    float                   mipLodBi=
as;
    VkBool32                anisotropyEnable;
    float                   maxAniso=
tropy;
    VkBool32                compareEnable;
    VkCompareOp             compareOp;
    float                   minLod;
    float                   maxLod;
    VkBorderColor           borderColor;
    VkBool32                unnormalizedCoordinates;
} VkSamplerCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • magFilter is a VkFilter value specifying the = magnification filter to apply to lookups.

  • minFilter is a VkFilter value specifying the = minification filter to apply to lookups.

  • mipmapMode is a VkSamplerMipmapMode value specifying the mipmap filter to apply to lookups.

  • addressModeU is a VkSamplerAddressMod= e value specifying the addressing mode for outside [0..1] range for U coordinate.

  • addressModeV is a VkSamplerAddressMod= e value specifying the addressing mode for outside [0..1] range for V coordinate.

  • addressModeW is a VkSamplerAddressMod= e value specifying the addressing mode for outside [0..1] range for W coordinate.

  • mipLodBias is the bias t= o be added to mipmap LOD (level-of-detail) calculation and bias provided by image sampling functions in SPIR-V, as described in the Level-of-Detail Operation section.

  • anisotropyEnable is <= code>VK_TRUE to enable anisotropic filtering, as described in the Texel Anisotropic Filtering section, or VK_FALSE otherwise.

  • maxAnisotropy is the anisotropy value clamp used by the sam= pler when anisotropyEnable is VK_TRUE. If anisotropyEnable is VK_FALSE, maxAnisotr= opy is ignored.

  • compareEnable is VK_TRUE to enable comparison = against a reference value during lookups, or VK_FALSE otherwise.

    • Note: Some implementations will default to shader state if this member does not match.

  • compareOp is a VkCompareOp value specifyin= g the comparison function to apply to fetched data before filtering as described in the Depth Compare Operation section.

  • minLod and maxLod are the values used to clamp= the computed LOD value, as described in the Level-of= -Detail Operation section.

  • borderColor is a VkBorderColor value spe= cifying the predefined border color to use.

  • unnormalizedCoordi= nates controls whether to use unnormalized or normalized texel coordinates to address texels of the image. When set to VK_TRUE, the range of the image coordinates used t= o lookup the texel is in the range of zero to the image dimensions for x, y and z. When set to VK_FALSE the range of image coordinates is zero to one. When unnormalizedCoordinates is VK_TRUE, samplers= have the following requirements:

    • minFilter and magFilter must be equal.

    • mipmapMode must be = VK_SAMPLER_MIPMAP_MODE_NEAREST.

    • minLod and maxLod mus= t be zero.

    • addressModeU and addressModeV must each be either VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER.

    • anisotropyEnable must be = VK_FALSE.

    • compareEnable must be VK_FALSE.

    • The sampler must not enable sampler Y= =E2=80=99CBCR conversion.

  • When unnormalizedCoordinates is VK_TRUE, image= s the sampler is used with in the shader have the following requirements:

    • The viewType must be eith= er VK_IMAGE_VIEW_TYPE_1D or VK_IMAGE_VIEW_TYPE_2D.

    • The image view must have a single laye= r and a single mip level.

  • When unnormalizedCoordinates is VK_TRUE, image= built-in functions in the shader that use the sampler have the following requirements:

    • The functions must not use projection.=

    • The functions must not use offsets.

Mapping of OpenGL to Vulkan filter modes

magFilter values of VK_FILTER_NEAREST and VK_FILTER_LINEAR directly correspond to GL_NEAREST and GL_LINEAR m= agnification filters. minFilter and mipmapMode combine to correspond to= the similarly named OpenGL minification filter of GL_minFilter_MIPMAP_mipmapMode (e.g. minFilter of VK_FILTER_LINEAR and mip= mapMode of VK_SAMPLER_MIPMAP_MODE_NEAREST correspond to GL_LINEAR_MIPMAP_NEAREST).

There are no Vulkan filter modes that directly correspond to OpenGL minification filters of GL_LINEAR or GL_NEAREST, = but they can be emulated using VK_SAMPLER_MIPMAP_MODE_NEAREST, minLod =3D 0, and maxLod =3D 0.25, and using minFilter =3D VK= _FILTER_LINEAR or minFilter =3D VK_FILTER_NEAREST, respectively.

Note that using a maxLod of zero would cause magnification to always be performed, and the magFilter to always be used. This is valid, just not an exact match for OpenGL behavior. Clamping the maximum LOD to 0.25 allows the =CE=BB value to be non-zero and minification to be performed, while still always rounding down to the base level. If the minFilter and magFilter are equal, then us= ing a maxLod of zero also works.

The maximum number of sampler objects which can= be simultaneously created on a device is implementation-dependent and specified by the maxSamplerAllocationCount member of the VkPhysicalDeviceLimits structure. If maxSamplerAllocationCount is exceeded, vkCreateSample= r will return VK_ERROR_TOO_MANY_OBJECTS.

Since VkSampler is a non-dispatchable handle type, implem= entations may return the same handle for sampler st= ate vectors that are identical. In such cases, all such objects would only count once against the maxSamplerAllocationCount limit.

Valid Usage
  • The absolute value of mipLodBias must= be less than or equal to VkPhysicalDeviceLimits::maxSamplerLodBias

  • maxLod must be greater than = or equal to minLod

  • If the anisotropic sampling feature is not enabled, anisotropyEnable must be VK_FALSE

  • If anisotropyEnable is VK_TRUE, maxAnisotro= py must be between 1.0 and VkPhysicalDeviceLimits::maxSamplerAnisotropy, inc= lusive

  • If sampler Y=E2=80=99CBCR = conversion is enabled and VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCT= ION_FILTER_BIT is not set for the format, minFilter and magFilter must be equal to the sampler Y=E2=80=99CBCR conversion=E2=80= =99s chromaFilter

  • If unnormalizedCoordinates is VK_TRUE, minF= ilter and magFilter must be equal

  • If unnormalizedCoordinates is VK_TRUE, mipm= apMode must be VK_SAMPLER_MIPMAP_MODE_NEAR= EST

  • If unnormalizedCoordinates is VK_TRUE, minL= od and maxLod must be zero

  • If unnormalizedCoordinates is VK_TRUE, addr= essModeU and addressModeV must each b= e either VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER

  • If unnormalizedCoordinates is VK_TRUE, anisotropyEnable must be VK_FALSE

  • If unnormalizedCoordinates is VK_TRUE, comp= areEnable must be VK_FALSE

  • If any of addressModeU, addressModeV or add= ressModeW are VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, borderColor= must be a valid VkBorderCo= lor value

  • If sampler Y=E2=80=99CBCR = conversion is enabled, addressModeU, addressModeV, and ad= dressModeW must be VK_SAMPLER_ADDRESS_MODE_CLA= MP_TO_EDGE, anisotropyEnable must be VK_FALSE, and unnormalizedCoordinates must= be VK_FALSE

  • The sampler reduction mode must be set to VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT if sampler Y=E2=80=99CBCR con= version is enabled

  • If the VK_KHR_sampler_mirror_cla= mp_to_edge extension is not enabled, addressModeU, addressModeV and add= ressModeW must not be VK_SAMPLER_ADDRESS_MODE= _MIRROR_CLAMP_TO_EDGE

  • If compareEnable is VK_TRUE, compareOp must be a valid VkCompareOp value

  • If either magFilter or minFilter is VK_FILTER_CUBIC_IMG, anisotropyEnable must be VK_FALSE

  • If either magFilter or minFilter is VK_FILTER_CUBIC_IMG, the reductionMode member of VkSamplerReductionModeCreateInfoEXT must be VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT

  • If compareEnable is VK_TRUE, the reductionM= ode member of VkSamplerReductionModeCreateInfoEXT= must be VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT

Valid Usage (Implicit)
typedef VkFlags VkSamplerCreateFlags;

VkSamplerCreateFlags is a bitmask type for setting a mask, = but is currently reserved for future use.

If the pNext chain of VkSamplerCreateI= nfo includes a VkSamplerReductionModeCreateInfoEXT structure, then that struc= ture includes a mode that controls how texture filtering combines texel values.<= /p>

The VkSamplerReductionModeCreateInfoEXT structure is define= d as:

typedef struct VkSamplerReducti=
onModeCreateInfoEXT {
    VkStructureType              sType;
    const void*                  pNext;
    VkSamplerReductionModeEXT    reductionMode;
} VkSamplerReductionModeCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • reductionMode is an enum of type VkSamplerReductionModeEXT that controls how texture filtering combines texel values.

If this structure is not present, reductionMode is consider= ed to be VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT

  • reductionMode must b= e a valid VkSamplerReductionModeEXT value

Reduction modes are specified by VkSamplerRed= uctionModeEXT, which takes values:

typedef enum VkSamplerReduction=
ModeEXT {
    VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT =3D 0,
    VK_SAMPLER_REDUCTION_MODE_MIN_EXT =3D 1,
    VK_SAMPLER_REDUCTION_MODE_MAX_EXT =3D 2,
} VkSamplerReductionModeEXT;
  • VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT specifies th= at texel values are combined by computing a weighted average of values in the footprint, using weights as specified in the image operations chapter.

  • VK_SAMPLER_REDUCTION_MODE_MIN_EXT specifies that texel valu= es are combined by taking the component-wise minimum of values in the footprint with non-zero weights.

  • VK_SAMPLER_REDUCTION_MODE_MAX_EXT specifies that texel valu= es are combined by taking the component-wise maximum of values in the footprint with non-zero weights.

Possible values of the VkSamplerCreateInfo::magFilter and minFilter parameters, specifying filters used for texture look= ups, are:

typedef enum VkFilter {
    VK_FILTER_NEAREST =3D 0,
    VK_FILTER_LINEAR =3D 1,
    VK_FILTER_CUBIC_IMG =3D 1000015000,
} VkFilter;
  • VK_FILTER_NEAREST specifies nearest filtering.

  • VK_FILTER_LINEAR specifies linear filtering.

  • VK_FILTER_CUBIC_IMG specifies cubic filtering.

These filters are described in detail in Texel Filtering.

Possible values of the VkSamplerCreateInfo::mipmapMode, specifying the mipmap mode used for texture lookups, are:

typedef enum VkSamplerMipmapMod=
e {
    VK_SAMPLER_MIPMAP_MODE_NEAREST =3D 0,
    VK_SAMPLER_MIPMAP_MODE_LINEAR =3D 1,
} VkSamplerMipmapMode;
  • VK_SAMPLER_MIPMAP_MODE_NEAREST specifies nearest filtering.=

  • VK_SAMPLER_MIPMAP_MODE_LINEAR specifies linear filtering.

These modes are described in detail in Texel Filtering.

Possible values of the VkSamplerCreateInfo::addressMode* parameters, specifying the behavior of sampling with coordinates outside th= e range [0,1] for the respective u, v, or w coor= dinate as defined in the Wrapping Operation section, are:

typedef enum VkSamplerAddressMo=
de {
    VK_SAMPLER_ADDRESS_MODE_REPEAT =3D 0,
    VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT =3D 1,
    VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE =3D 2,
    VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER =3D 3,
    VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE =3D 4,
} VkSamplerAddressMode;
  • VK_SAMPLER_ADDRESS_MODE_REPEAT specifies that the repeat wr= ap mode will be used.

  • VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT specifies that the mirrored repeat wrap mode will be used.

  • VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE specifies that the cl= amp to edge wrap mode will be used.

  • VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER specifies that the = clamp to border wrap mode will be used.

  • VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE specifies that= the mirror clamp to edge wrap mode will be used. This is only valid if the VK_KHR= _sampler_mirror_clamp_to_edge extension is enabled.

Possible values of VkSamplerCreateInfo::b= orderColor, specifying the border color used for texture lookups, are:

typedef enum VkBorderColor {
    VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK =3D 0,
    VK_BORDER_COLOR_INT_TRANSPARENT_BLACK =3D 1,
    VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK =3D 2=
,
    VK_BORDER_COLOR_INT_OPAQUE_BLACK =3D 3,
    VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE =3D 4=
,
    VK_BORDER_COLOR_INT_OPAQUE_WHITE =3D 5,
} VkBorderColor;
  • VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK specifies a transpa= rent, floating-point format, black color.

  • VK_BORDER_COLOR_INT_TRANSPARENT_BLACK specifies a transpare= nt, integer format, black color.

  • VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK specifies an opaque, floating-point format, black color.

  • VK_BORDER_COLOR_INT_OPAQUE_BLACK specifies an opaque, integ= er format, black color.

  • VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE specifies an opaque, floating-point format, white color.

  • VK_BORDER_COLOR_INT_OPAQUE_WHITE specifies an opaque, integ= er format, white color.

These colors are described in detail in Texe= l Replacement.

To destroy a sampler, call:

void vkDestroySampler(
    VkDevice                                    device,
    VkSampler                                   sampler,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the sampler.

  • sampler is the sampler to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to sampler must have completed execution

  • If VkAllocationCallbacks were provided when sampler was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when sampler was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice h= andle

  • If sampler<= /code> is not VK_NULL_HANDLE, sampler must be a valid VkSampler handle=

  • If pAllo= cator is not NULL, pAllocator must be a valid pointer to a valid VkAllocation= Callbacks structure

  • If sampler is a valid handle, it must have been = created, allocated, or retrieved from device

Host Synchronization
  • Host access to sampler must be externally synchronized

12.1. Sampler Y=E2=80=99CBC= R conversion

To create a sampler with Y=E2=80=99CBCR conversion= enabled, add a VkSamplerYcbcrConversionInfo to the pNext chain of the VkSamplerCreateInfo structure. To create a sampler Y=E2=80=99CBCR conversion, the samplerYcbcrConversion feature must be enabled. Conversion must be fixed at pipeline crea= tion time, through use of a combined image sampler with an immutable sampler in VkDescriptorSetLayoutBinding.

A VkSamplerYcbcrConversionInfo must be provided for samplers to be used with image views that access VK_IMAGE_ASPECT_COLOR_BIT if= the format appears in Form= ats requiring sampler Y=E2=80=99CBCR conversion for <= code>VK_IMAGE_ASPECT_COLOR_BIT image views , or if the image view has an external format .

The VkSamplerYcbcrConversionInfo structure is defined as:

typedef struct VkSamplerYcbcrCo=
nversionInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkSamplerYcbcrConversion    conversion;
} VkSamplerYcbcrConversionInfo;

or the equivalent

typedef VkSamplerYcbcrConversionInfo VkSamplerYcbcrConversionI=
nfoKHR;
Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_S= AMPLER_YCBCR_CONVERSION_INFO

  • conversion must be a valid VkSamplerYcbcrConversion handle

A sampler Y=E2=80=99CBCR conversion is an opaque r= epresentation of a device-specific sampler Y=E2=80=99CBCR conversion des= cription, represented as a VkSamplerYcbcrConversion handle:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkSamplerYcbcrConversion)

or the equivalent

typedef VkSamplerYcbcrConversion VkSamplerYcbcrConversionKHR;<=
/code>

To create a VkSamplerYcbcrConversion, call= :

VkResult vkCreateS=
amplerYcbcrConversion(
    VkDevice                                    device,
    const VkSamplerYcbcrConversionCreateIn=
fo*   pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSamplerYcbcrConversion*                   pYcbcrConversion);

or the equivalent command

VkResult vkCreateS=
amplerYcbcrConversionKHR(
    VkDevice                                    device,
    const VkSamplerYcbcrConversionCreateIn=
fo*   pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSamplerYcbcrConversion*                   pYcbcrConversion);
  • device is the logical device that creates the sampler Y=E2= =80=99CBCR conversion.

  • pCreateInfo is a pointer to an instance of the VkSamplerYcbcrConversionCreateInfo = specifying the requested sampler Y=E2=80=99CBCR conversion.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pYcbcrConversion points to a VkSa= mplerYcbcrConversion handle in which the resulting sampler Y=E2=80=99CBCR convers= ion is returned.

The interpretation of the configured sampler Y=E2=80=99CBCR conversion is described in more detail in the description of sampler Y=E2=80=99CBCR conversion = in the Image Operations chapter.

Valid Usage
Valid Usage (Implicit)
  • device must be a valid VkD= evice handle

  • = pCreateInfo must be a valid= pointer to a valid VkSamplerYcbcrConversionCreateInfo structu= re

  • = If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • pYcbcrConversion must = be a valid pointer to a VkSamplerYcbcrConversion handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkSamplerYcbcrConversionCreateInfo structure is defined= as:

typedef struct VkSamplerYcbcrCo=
nversionCreateInfo {
    VkStructureType                  sType;
    const void*                      pNext;
    VkFormat                         format;
    VkSamplerYcbcrModelConversion    ycbcrModel;
    VkSamplerYcbcrRange              ycbcrRange;
    VkComponentMapping               components;
    VkChromaLocation                 xChromaOffset;
    VkChromaLocation                 yChromaOffset;
    VkFilter                         chromaFilter;
    VkBool32                         forceExplicitReconstruction;
} VkSamplerYcbcrConversionCreateInfo;

or the equivalent

typedef VkSamplerYcbcrConversionCreateInfo VkSamplerYcbcrConve=
rsionCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • format is the format of the image from which color informat= ion will be retrieved.

  • ycbcrModel describes the color matrix for conversion betwee= n color models.

  • ycbcrRange describes whether the encoded values have headro= om and foot room, or whether the encoding uses the full numerical range.

  • components applies a swizzle based on VkComponentSwizzle enums prior to range expansion and color model conversion.

  • xChromaOffset describes the sample location associated with downsampled chroma channels in the x dimension. xChromaOffset has no effect for formats in which chroma channe= ls are the same resolution as the luma channel.

  • yChromaOffset describes the sample location associated with downsampled chroma channels in the y dimension. yChromaOffset has no effect for formats in which the chroma channels are not downsampled vertically.

  • chromaFilter is the filter for chroma reconstruction.

  • forceExplicitReconstruction can be used to ensure that reconstruction is done explicitly, if supported.

Note

Setting forceExplicitReconstruction to VK_TRUE= may have a performance penalty on implementations where explicit reconstruction is not the default mode of operation.

If the pNext chain has an instance of VkExternalFormatANDROID with non-zero externalFormat member, the sampler Y=E2=80=99CBCR conversion object represents an external format conversion, and format<= /code> must be VK_FORMAT_UNDEFINED. Such conversions must only be used to sam= ple image views with a matching external format. When creating an external format conversion, the value of components<= /code> is ignored.

Valid Usage
Valid Usage (Implicit)

If chromaFilter is VK_FILTER_NEAREST, chroma s= amples are reconstructed to luma channel resolution using nearest-neighbour sampling. Otherwise, chroma samples are reconstructed using interpolation. More details can be found in the description of sampler Y=E2=80=99CBCR conversion = in the Image Operations chapter.

VkSamplerYcbcrModelConversion defines= the conversion from the source color model to the shader color model. Possible values are:

typedef enum VkSamplerYcbcrMode=
lConversion {
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY =3D 0,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY =3D 1,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 =3D 2,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 =3D 3,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 =3D 4,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR =3D VK_SAMPLER_YCBCR=
_MODEL_CONVERSION_RGB_IDENTITY,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR =3D VK_SAMPLER_YCB=
CR_MODEL_CONVERSION_YCBCR_IDENTITY,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR =3D VK_SAMPLER_YCBCR_MO=
DEL_CONVERSION_YCBCR_709,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR =3D VK_SAMPLER_YCBCR_MO=
DEL_CONVERSION_YCBCR_601,
    VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR =3D VK_SAMPLER_YCBCR_M=
ODEL_CONVERSION_YCBCR_2020,
} VkSamplerYcbcrModelConversion;

or the equivalent

typedef VkSamplerYcbcrModelConversion VkSamplerYcbcrModelConve=
rsionKHR;
  • VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY specifies th= at the input values to the conversion are unmodified.

  • VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY specifies = no model conversion but the inputs are range expanded as for Y=E2=80=99CB= CR.

  • VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 specifies the c= olor model conversion from Y=E2=80=99CBCR to R=E2=80=99G= =E2=80=99B' defined in BT.709 and described in the =E2=80=9CBT.709 Y=E2=80=99CBCR conve= rsion=E2=80=9D section of the Khronos Data Format Specification.

  • VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 specifies the c= olor model conversion from Y=E2=80=99CBCR to R=E2=80=99G= =E2=80=99B' defined in BT.601 and described in the =E2=80=9CBT.601 Y=E2=80=99CBCR conve= rsion=E2=80=9D section of the Khronos Data Format Specification.

  • VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 specifies the = color model conversion from Y=E2=80=99CBCR to R=E2=80=99G= =E2=80=99B' defined in BT.2020 and described in the =E2=80=9CBT.2020 Y=E2=80=99CBCR conv= ersion=E2=80=9D section of the Khronos Data Format Specification.

In the VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_* color mode= ls, for the input to the sampler Y=E2=80=99CBCR range expansion a= nd model conversion:

  • the Y (Y' luma) channel corresponds to the G channel of an RGB image.

  • the CB (CB or =E2=80=9CU=E2=80=9D blue color difference) chan= nel corresponds to the B channel of an RGB image.

  • the CR (CR or =E2=80=9CV=E2=80=9D red color difference) chann= el corresponds to the R channel of an RGB image.

  • the alpha channel, if present, is not modified by color model conversion.

These rules reflect the mapping of channels after the channel swizzle operation (controlled by VkSamplerYcbcrConversionCreateInfo:= :components).

Note

For example, an =E2=80=9CYUVA=E2=80=9D 32-bit format comprising four 8-b= it channels can be implemented as VK_FORMAT_R8G8B8A8_UNORM with a component mappi= ng:

  • components.a =3D VK_COMPONENT_SWIZZLE_IDENTITY=

  • components.r =3D VK_COMPONENT_SWIZZLE_B

  • components.g =3D VK_COMPONENT_SWIZZLE_R

  • components.b =3D VK_COMPONENT_SWIZZLE_G

The VkSamplerYcbcrRange enum describes whether = color channels are encoded using the full range of numerical values or whether values are reserved for headroom and foot room. VkSamplerYcbcrRange is defined as:

typedef enum VkSamplerYcbcrRang=
e {
    VK_SAMPLER_YCBCR_RANGE_ITU_FULL =3D 0,
    VK_SAMPLER_YCBCR_RANGE_ITU_NARROW =3D 1,
    VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR =3D VK_SAMPLER_YCBCR_RANGE_ITU_FULL=
,
    VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR =3D VK_SAMPLER_YCBCR_RANGE_ITU_NA=
RROW,
} VkSamplerYcbcrRange;

or the equivalent

typedef VkSamplerYcbcrRange VkSamplerYcbcrRangeKHR;
  • VK_SAMPLER_YCBCR_RANGE_ITU_FULL specifies that the full ran= ge of the encoded values are valid and interpreted according to the ITU =E2=80=9C= full range=E2=80=9D quantization rules.

  • VK_SAMPLER_YCBCR_RANGE_ITU_NARROW specifies that headroom a= nd foot room are reserved in the numerical range of encoded values, and the remaining values are expanded according to the ITU =E2=80=9Cnarrow range=E2= =80=9D quantization rules.

The formulae for these conversions is described in the Sampler Y=E2=80=99CBCR Range Expansion section of the Image Operations chapter.

No range modification takes place if ycbcrModel is VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; the ycbc= rRange field of VkSamplerYcbcrConversionCreateInfo is ignored in this= case.

The VkChromaLocation enum, which defines the locat= ion of downsampled chroma channel samples relative to the luma samples, is defined as:

typedef enum VkChromaLocation {
    VK_CHROMA_LOCATION_COSITED_EVEN =3D 0,
    VK_CHROMA_LOCATION_MIDPOINT =3D 1,
    VK_CHROMA_LOCATION_COSITED_EVEN_KHR =3D VK_CHROMA_LOCATION_COSITED_EVEN=
,
    VK_CHROMA_LOCATION_MIDPOINT_KHR =3D VK_CHROMA_LOCATION_MIDPOINT,
} VkChromaLocation;

or the equivalent

typedef VkChromaLocation VkChromaLocationKHR;
  • VK_CHROMA_LOCATION_COSITED_EVEN specifies that downsampled = chroma samples are aligned with luma samples with even coordinates.

  • VK_CHROMA_LOCATION_MIDPOINT specifies that downsampled chro= ma samples are located half way between each even luma sample and the nearest higher odd luma sample.

To destroy a sampler Y=E2=80=99CBCR conversion, ca= ll:

void vkDestroySamplerYcbcrConversion(
    VkDevice                                    device,
    VkSamplerYcbcrConversion                    ycbcrConversion,
    const VkAllocationCallbacks*          =
      pAllocator);

or the equivalent command

void vkDestroySamplerYcbcrConversionKHR(
    VkDevice                                    device,
    VkSamplerYcbcrConversion                    ycbcrConversion,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the Y=E2=80=99C<= sub>BCR conversion.

  • ycbcrConversion is the conversion to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage (Implicit)
Host Synchronization
  • Host access to ycbcrConversion mus= t be externally synchronized

13. Resource Descriptors

Shaders access resources via variables decorated with a descriptor set a= nd binding number that link them to a descriptor in a descriptor set. The shader interface mapping to bound descriptor sets is described in the Shader Resource Interface section.

13.1. Descriptor Types

There are a number of different types of descriptor supported by Vulkan, corresponding to different resources or usage. The following sections describe the API definitions of each descriptor type= . The mapping of each type to SPIR-V is listed in the Shader Resource and Descriptor Type Correspondence and S= hader Resource and Storage Class Correspondence tables in the Shader Interfaces chapter.

13.1.1. Storage Image

A storage image (VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)= is a descriptor type associated with an image resource via an image view that load, store, and atomic operations can be performed on.

Storage image loads are supported in all shader stages for image views w= hose format features contain VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT.

Stores to storage images are supported in compute shaders for image view= s whose format features contain VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT.

Atomic operations on storage images are supported in compute shaders for image views whose format features contain VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_B= IT.

When the fragmentStore= sAndAtomics feature is enabled, stores and atomic operations are also supported for storage images in fragment shaders with the same set of image formats as supported in compute shaders. When the vertexPipe= lineStoresAndAtomics feature is enabled, stores and atomic operations are also supported in vertex, tessellation, and geometry shaders with the same set of image formats as supported in compute shaders.

The image subresources for a storage image must= be in the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or VK_IMAGE_LAYOUT_GENERAL layout in order to access its data in = a shader.

13.1.2. Sampler

A sampler descriptor (VK_DESCRIPTOR_TYPE_SAMPLER) = is a descriptor type associated with a sampler object, used to control the behaviour of sampling operations performed on a sampled image.

13.1.3. Sampled Image

A sampled image (VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)= is a descriptor type associated with an image resource via an image view that sampling operations can be performed on.

Shaders combine a sampled image variable and a sampler variable to perfo= rm sampling operations.

The image subresources for a sampled image must= be in the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, or VK_IMAGE_LAYOUT_GENERAL layout in order to access its data in = a shader.

13.1.5. Uniform Texel Buffer

Uniform texel buffers define a tightly-packed 1-dimensional linear array= of texels, with texels going through format conversion when read in a shader i= n the same way as they are for an image.

Load operations from uniform texel buffers are supported in all shader stages for image formats which report support for the VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_B= IT feature bit via vkGetPhysicalDeviceFor= matProperties in VkFormatProperties::bufferFeatures.

13.1.6. Storage Texel Buffer

A storage texel buffer (VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_= BUFFER) is a descriptor type associated with a buffer resource via a buffer view that formatted load, store, and atomic operations can be performed on.

Storage texel buffers define a tightly-packed 1-dimensional linear array= of texels, with texels going through format conversion when read in a shader i= n the same way as they are for an image. Unlike uniform texel buffers, these buffers can also be written to in the same way as for storage images.

Storage texel buffer loads are supported in all shader stages for texel buffer formats which report support for the VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_B= IT feature bit via vkGetPhysicalDeviceFor= matProperties in VkFormatProperties::bufferFeatures.

Stores to storage texel buffers are supported in compute shaders for tex= el buffer formats which report support for the VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT feature via vkGetPhysicalDeviceFormatProperties in VkFormatProperties::bufferFeatures.

Atomic operations on storage texel buffers are supported in compute shad= ers for texel buffer formats which report support for the VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_A= TOMIC_BIT feature via vkGetPhysicalDeviceFormatP= roperties in VkFormatProperties::bufferFeatures.

When the fragmentStore= sAndAtomics feature is enabled, stores and atomic operations are also supported for storage texel buffers in fragment shaders with the same set of texel buffer formats as supported in compute shaders. When the vertexPipe= lineStoresAndAtomics feature is enabled, stores and atomic operations are also supported in vertex, tessellation, and geometry shaders with the same set of texel buffer formats as supported in compute shaders.<= /p>

13.1.7. Storage Buffer

A storage buffer (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) is a descriptor type associated with a buffer resource directly, described in a shader as a structure with various members that load, store, and atomic operations can be performed on= .

Note

Atomic operations can only be performe= d on members of certain types as defined in the SPIR-V environment appendix.

13.1.8. Uniform Buffer

A uniform buffer (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) is a descriptor type associated with a buffer resource directly, described in a shader as a structure with various members that load operations can be performed on.

13.1.9. Dynamic Uniform Buff= er

A dynamic uniform buffer (VK_DESCRIPTOR_TYPE_UNIFORM_BUFF= ER_DYNAMIC) is almost identical to a uniform buffer, and differs only in how the offset into the buffer is specified. The base offset calculated by the VkDescriptorBuffe= rInfo when initially updating the descriptor set is added to a dynamic offset when binding the descriptor set.

13.1.10. Dynamic Storage Buf= fer

A dynamic storage buffer (VK_DESCRIPTOR_TYPE_STORAGE_BUFF= ER_DYNAMIC) is almost identical to a storage buffer, and differs only in how the offset into the buffer is specified. The base offset calculated by the VkDescriptorBuffe= rInfo when initially updating the descriptor set is added to a dynamic offset when binding the descriptor set.

13.1.11. Input Attachment

An input attachment (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT<= /code>) is a descriptor type associated with an image resource via an image view that can<= /strong> be used for framebuffer local load operations = in fragment shaders.

All image formats that are supported for color attachments (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) or depth/stencil atta= chments (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) for a given i= mage tiling mode are also supported for input attachments.

The image subresources for an input attachment = must be in the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, or VK_IMAGE_LAYOUT_GENERAL layout in order to access its data in = a shader.

13.2. Descriptor Sets

Descriptors are grouped together into descriptor set objects. A descriptor set object is an opaque object that contains storage for a set of descriptors, where the types and number of descriptors is defined by a descriptor set layout. The layout object may be used to define t= he association of each descriptor binding with memory or other implementation resources. The layout is used both for determining the resources that need to be associated with the descriptor set, and determining the interface between shader stages and shader resources.

13.2.1. Descriptor Set Layout

A descriptor set layout object is defined by an array of zero or more descriptor bindings. Each individual descriptor binding is specified by a descriptor type, a count (array size) of the number of descriptors in the binding, a set of shader stages that can access the binding= , and (if using immutable samplers) an array of sampler descriptors.

Descriptor set layout objects are represented by VkDescriptorSetLa= yout handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDescriptorSetLayout)

To create descriptor set layout objects, call:

VkResult vkCreateD=
escriptorSetLayout(
    VkDevice                                    device,
    const VkDescriptorSetLayoutCreateInfo*=
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDescriptorSetLayout*                      pSetLayout);
  • device is the logical device that creates the descriptor se= t layout.

  • pCreateInfo is a pointer to an instance of the VkDescriptorSetLayoutCreateInfo struct= ure specifying the state of the descriptor set layout object.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pSetLayout points to a VkDescriptorS= etLayout handle in which the resulting descriptor set layout object is returned.

Valid Usage (Implicit)
  • d= evice must be a valid VkDevi= ce handle

  • pCreateInfo must be a valid po= inter to a valid VkDescriptorSetLayoutCreateInfo structure

  • If = pAllocator is not NULL, pAllocator <= strong class=3D"purple">must be a valid pointer to a valid V= kAllocationCallbacks structure

  • pSetLayout must be a valid poin= ter to a VkDescriptorSetLayout handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Information about the descriptor set layout is passed in an instance of = the VkDescriptorSetLayoutCreateInfo structure:

typedef struct VkDescriptorSetL=
ayoutCreateInfo {
    VkStructureType                        sType;
    const void*                            pNext;
    VkDescriptorSetLayoutCreateFlags       flags;
    uint32_t                               bindingCount;
    const VkDescriptorSetLayoutBinding*   =
 pBindings;
} VkDescriptorSetLayoutCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkDescriptorSetLayoutCreateFlagBits= specifying options for descriptor set layout creation.

  • bindingCount is the number of elements in pBindings.

  • pBindings is a pointer to an array of VkDescriptorSetLayoutBinding structures.<= /p>

Valid Usage
  • The VkDescriptorSetLayoutBinding::b= inding members of the elements of the pBindings array must<= /strong> each have different values.

  • If flags contains VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, then = all elements of pBindings must n= ot have a descriptorType of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC

  • If flags contains VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, then = the total number of elements of all bindings must be less than or equal to VkPhysicalDevicePushDescriptor= PropertiesKHR::maxPushDescriptors

  • If any binding has the VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT bit set, flags must include VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT=

  • If any binding has the VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT bit set, then = all bindings must not have descriptorTy= pe of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC

Valid Usage (Implicit)

Bits which can be set in VkDescriptorSetLayoutCreateInfo::flags to specify options for descriptor set layout are:

typedef enum VkDescriptorSetLay=
outCreateFlagBits {
    VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR =3D 0x00000001,
    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT =3D 0x00000002,
} VkDescriptorSetLayoutCreateFlagBits;
  • VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR spe= cifies that descriptor sets must not be allocate= d using this layout, and descriptors are instead pushed by vkCmdPushDescr= iptorSetKHR.

  • VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT specifies that descriptor sets using this layout m= ust be allocated from a descriptor pool created with the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT bit set. Descriptor set layouts created with this bit set have alternate limits for the maximum number of descriptors per-stage and per-pipeline layout. The non-UpdateAfterBind limits only count descriptors in sets created without this flag. The UpdateAfterBind limits count all descriptors, but the limits may be higher than the non-UpdateAfterBind limits.

typedef VkFlags VkDescriptorSetLayoutCreateFlags;

VkDescriptorSetLayoutCreateFlags is a bitmask type for sett= ing a mask of zero or more VkDescriptorSetLayoutC= reateFlagBits.

The VkDescriptorSetLayoutBinding structure is defined as:

typedef struct VkDescriptorSetL=
ayoutBinding {
    uint32_t              binding;
    VkDescriptorType      descriptorType;
    uint32_t              descriptorCount;
    VkShaderStageFlags    stageFlags;
    const VkSampler*      pImmutableSample=
rs;
} VkDescriptorSetLayoutBinding;
  • binding is the binding number of this entry and corresponds= to a resource of the same binding number in the shader stages.

  • descriptorType is a VkDescriptorType = specifying which type of resource descriptors are used for this binding.

  • descriptorCount is the number of descriptors contained in t= he binding, accessed in a shader as an array. If descriptorCount is zero this binding entry is reserved and = the resource must not be accessed from any st= age via this binding within any pipeline using the set layout.

  • stageFlags member is a bitmask of Vk= ShaderStageFlagBits specifying which pipeline shader stages can access a resource for this binding. VK_SHADER_STAGE_ALL is a shorthand specifying that all defined shader stages, including any additional stages defined by extensions, can access the resource.

    If a shader stage is not included in stageFlags, then a res= ource must not be accessed from that stage via this binding within any pipeline using the set layout. Other than input attachments which are limited to the fragment shader, ther= e are no limitations on what combinations of stages = can use a descriptor binding, and in particular a binding can = be used by both graphics stages and the compute stage.

  • pImmutableSamplers affects initialization of samplers. If descriptorType specifies a VK_DESCRIPTOR_TYPE_SAMPLER= or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER type descriptor, the= n pImmutableSamplers can be us= ed to initialize a set of immutable samplers. Immutable samplers are permanently bound into the set layout; later binding a sampler into an immutable sampler slot in a descriptor set is not allowed. If pImmutableSamplers is not NULL, then it is con= sidered to be a pointer to an array of sampler handles that will be consumed by the set layout and used for the corresponding binding. If pImmutableSamplers is NULL, then the sampler s= lots are dynamic and sampler handles must be bound= into descriptor sets using this layout. If descriptorType is not one of these descriptor types, then pImmutableSamplers is ignored.

The above layout definition allows the descriptor bindings to be specifi= ed sparsely such that not all binding numbers between 0 and the maximum bindin= g number need to be specified in the pBindings array. Bindings that are not specified have a descriptorCount and stageFlags of zero, and the descriptorType is tre= ated as undefined. However, all binding numbers between 0 and the maximum binding number in th= e VkDescriptorSetLayoutCreateInfo::pBindings array may consume memory in the descriptor set layout even if not all descriptor bindings are used, though it should not consume additi= onal memory from the descriptor pool.

Note

The maximum binding number specified should be as compact as possible to avoid wasted memory.

Valid Usage
  • If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER o= r VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and descriptorCount is not 0 and pImmutableSamp= lers is not NULL, pImmutableSamplers must be a valid pointer to an array of descriptorCount valid VkSampler handles

  • If descriptorCount is not 0, stageFlags must be a valid combination of VkShaderStageFlagBits values

  • If descriptorType is VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT= and descriptorCount is not 0, then stageFlags must be 0 or VK_SHADER_STAGE_FRAGMENT_BIT

If the pNext chain of a Vk= DescriptorSetLayoutCreateInfo structure includes a VkDescriptorSetLayoutBindingFlagsCreateInfoEXT structure, then that structure includes an array of flags, one for each descriptor set layout binding.

typedef struct VkDescriptorSetL=
ayoutBindingFlagsCreateInfoEXT {
    VkStructureType                       sType;
    const void*                           pNext;
    uint32_t                              bindingCount;
    const VkDescriptorBindingFlagsEXT*    =
pBindingFlags;
} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • bindingCount is zero or the number of elements in pBindingFlags.

  • pBindingFlags is a pointer to an array of VkDescriptorBindingFlagsEXT bitfields, one= for each descriptor set layout binding.

If bindingCount is zero or if this structure is not in the = pNext chain, the VkDescriptorBindingFlagsEXT for= each descriptor set layout binding is considered to be zero. Otherwise, the descriptor set layout binding at VkDescriptorSetLayoutCreateInfo::pBindings[i] uses the flags in pBindingFlags[i].

Valid Usage
  • If bindingCount is not zero, bindingCount must equal VkDescriptorSetLayoutCreateInfo::bindingCount

  • If VkDescriptorSetLayoutCreateInfo::flags includes VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, then = all elements of pBindingFlags must not include VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT, VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT, or VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT

  • If an element of pBindingFlags includes VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT, then = all other elements of VkDescriptorSetLayoutCre= ateInfo::pBindings must have a smaller value of bindin= g

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingUniformBufferUpdateAfterBind<= /code> is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER mus= t not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingSampledImageUpdateAfterBind is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, or VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE must= not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingStorageImageUpdateAfterBind is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE must= not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingStorageBufferUpdateAfterBind<= /code> is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER mus= t not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingUniformTexelBufferUpdateAfter= Bind is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER must not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingStorageTexelBufferUpdateAfter= Bind is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER must not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT

  • All bindings with descriptor type VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC must not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingUpdateUnusedWhilePending is not enabled, all elements of pBindingFlags must not include VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingPartiallyBound is not enabled, all elements of pBindingFlags must not include VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT

  • If VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingVariableDescriptorCount is not enabled, all elements of pBindingFlags must not include VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT

  • If an element of pBindingFlags includes VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT, that element=E2=80=99s descriptorType must= not be VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC

Valid Usage (Implicit)
  • sType must be V= K_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT=

  • If bindingCount is not 0, pBindingFlags must be a valid po= inter to an array of bindingCount valid combinations of VkDescriptorBindingFlagBitsEXT values

  • Each element of pBindingFlags must not be 0

Bits which can be set in each element = of VkDescriptorSetLayoutBindin= gFlagsCreateInfoEXT::pBindingFlags to specify options for the corresponding descriptor set layout binding are:

typedef enum VkDescriptorBindin=
gFlagBitsEXT {
    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT =3D 0x00000001,
    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT =3D 0x00000002,
    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT =3D 0=
x00000004,
    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT =3D 0x00000008,
} VkDescriptorBindingFlagBitsEXT;
  • VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT indicates t= hat if descriptors in this binding are updated between when the descriptor set is bound in a command buffer and when that command buffer is submitted to a queue, then the submission will use the most recently set descriptors for this binding and the updates do not invalidate the command buffer. Descriptor bindings created with this flag are also partially exempt from the external synchronization requirement in vkUpdateDescriptorSetWithTemplateKHR<= /a> and vkUpdateDescriptorSets. They can be updated concurrently with the= set being bound to a command buffer in another thread, but not concurrently with the set being reset or freed.

  • VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT indicates tha= t descriptors in this binding that are not dynamically used need not contain valid descriptors at the time the descriptors are consumed. A descriptor is dynamically used if any shader invocation executes an instruction that performs any memory access using the descriptor.

  • VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT indicates that descriptors in this binding can be updated after a command buffer has bound this descriptor set, or while a command buffer that uses this descriptor set is pending execution, as long as the descriptors that are updated are not used by those command buffers. If VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT is also set, = then descriptors can be updated as long as the= y are not dynamically used by any shader invocations. If VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT is not set, t= hen descriptors can be updated as long as the= y are not statically used by any shader invocations.

  • VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT ind= icates that this descriptor binding has a variable size that will be specified when a descriptor set is allocated using this layout. The value of descriptorCount is treated as an upper bound on t= he size of the binding. This must only be used for the last bindi= ng in the descriptor set layout (i.e. the binding with the largest value of binding). For the purposes of counting against limits such as maxDescriptorSet* and maxPerStageDescriptor*, the= full value of descriptorCount is counted.

Note

Note that while VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT and VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT both= involve updates to descriptor sets after they are bound, VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT is a= weaker requirement since it is only about descriptors that are not used, whereas VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT requires the implementation to observe updates to descriptors that are used.

To query information about whether a descriptor set layout can be created, call:

void vkGetDescriptorSetLayoutSupport(
    VkDevice                                    device,
    const VkDescriptorSetLayoutCreateInfo*=
      pCreateInfo,
    VkDescriptorSetLayoutSupport*               pSupport);

or the equivalent command

void vkGetDescriptorSetLayoutSupportKHR(
    VkDevice                                    device,
    const VkDescriptorSetLayoutCreateInfo*=
      pCreateInfo,
    VkDescriptorSetLayoutSupport*               pSupport);
  • device is the logical device that would create the descript= or set layout.

  • pCreateInfo is a pointer to an instance of the VkDescriptorSetLayoutCreateInfo struct= ure specifying the state of the descriptor set layout object.

  • pSupport points to a VkDescri= ptorSetLayoutSupport structure in which information about support for the descriptor set layout object is returned.

Some implementations have limitations on what fits in a descriptor set w= hich are not easily expressible in terms of existing limits like maxDescriptorSet*, for example if all descriptor types share a= limited space in memory but each descriptor is a different size or alignment. This command returns information about whether a descriptor set satisfies this limit. If the descriptor set layout satisfies the VkPhysicalDeviceMaintenance3Propert= ies::maxPerSetDescriptors limit, this command is guaranteed to return VK_TRUE in VkDescriptorSetLayoutSupport::suppo= rted. If the descriptor set layout exceeds the VkPhysicalDeviceMaintenance3Propert= ies::maxPerSetDescriptors limit, whether the descriptor set layout is supported is implementation-dependent and may depend o= n whether the descriptor sizes and alignments cause the layout to exceed an internal limit.

This command does not consider other limits such as maxPerStageDescriptor*, and so a descriptor set layout that is supported according to this command must = still satisfy the pipeline layout limits such as maxPerStageDescriptor* in order to be used in a pipeline layout.

Note

This is a VkDevice query rather than VkPhysicalDevice= because the answer may depend on enabled features= .

Valid Usage (Implicit)

Information about support for the descriptor set layout is returned in a= n instance of the VkDescriptorSetLayoutSupport structure:

typedef struct VkDescriptorSetL=
ayoutSupport {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           supported;
} VkDescriptorSetLayoutSupport;

or the equivalent

typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupp=
ortKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • supported specifies whether the descriptor set layout can be created.

supported is set to VK_TRUE if the descriptor = set can be created, or else is set to VK_FALSE.

Valid Usage (Implicit)

If the pNext chain of a VkDes= criptorSetLayoutSupport structure includes a VkDescriptorSetVariableDescriptorCountLayoutSupportEXT structure, then that structure returns additional information about whether the descriptor set layout is supported.

typedef struct VkDescriptorSetV=
ariableDescriptorCountLayoutSupportEXT {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           maxVariableDescriptorCount;
} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • maxVariableDescriptorCount indicates the maximum number of descriptors supported in the highest numbered binding of the layout, if that binding is variable-sized.

If the create info includes a variable-sized descriptor, then supported is determined assuming the requested size of the variable-sized descriptor, and maxVariableDescriptorCount is s= et to the maximum size of that descriptor that can be successfully created (which is greater than or equal to the requested size passed in). If the create info does not include a variable-sized descriptor or if the VkPhysicalDeviceDescriptorIn= dexingFeaturesEXT::descriptorBindingVariableDescriptorCount feature is not enabled, then maxVariableDescriptorCount is set= to zero. For the purposes of this command, a variable-sized descriptor binding with = a descriptorCount of zero is treated as if the descriptorC= ount is one, and thus the binding is not ignored and the maximum descriptor count will be returned. If the layout is not supported, then the value written to maxVariableDescriptorCount is undefined.

Valid Usage (Implicit)
  • sType must be= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SU= PPORT_EXT

The following examples show a shader snippet using two descriptor sets, = and application code that creates corresponding descriptor set layouts.

GLSL example
//
// binding to a single sampled image descriptor in set 0
//
layout (set=3D0, binding=3D0) uniform texture2D mySampledImage;

//
// binding to an array of sampled image descriptors in set 0
//
layout (set=3D0, binding=3D1) uniform texture2D myArrayOfSampledImages[12];

//
// binding to a single uniform buffer descriptor in set 1
//
layout (set=3D1, binding=3D0) uniform myUniformBuffer
{
    vec4 myElement[32];
};
SPIR-V example
               .=
..
          %1 =3D OpExtInstImport "GLSL.std.450"
               ...
               OpName %9 "mySampledImage"
               OpName %14 "myArrayOfSampledImages"
               OpName %18 "myUniformBuffer"
               OpMemberName %18 0 "myElement"
               OpName %20 ""
               OpDecorate %9 DescriptorSet 0
               OpDecorate %9 Binding 0
               OpDecorate %14 DescriptorSet 0
               OpDecorate %14 Binding 1
               OpDecorate %17 ArrayStride 16
               OpMemberDecorate %18 0 Offset 0
               OpDecorate %18 Block
               OpDecorate %20 DescriptorSet 1
               OpDecorate %20 Binding 0
          %2 =3D OpTypeVoid
          %3 =3D OpTypeFunction %2
          %6 =3D OpTypeFloat 32
          %7 =3D OpTypeImage %6 2D 0 0 0 1 Unknown
          %8 =3D OpTypePointer UniformConstant %7
          %9 =3D OpVariable %8 UniformConstant
         %10 =3D OpTypeInt 32 0
         %11 =3D OpConstant %10 12
         %12 =3D OpTypeArray %7 %11
         %13 =3D OpTypePointer UniformConstant %12
         %14 =3D OpVariable %13 UniformConstant
         %15 =3D OpTypeVector %6 4
         %16 =3D OpConstant %10 32
         %17 =3D OpTypeArray %15 %16
         %18 =3D OpTypeStruct %17
         %19 =3D OpTypePointer Uniform %18
         %20 =3D OpVariable %19 Uniform
               ...
API example
VkResult myResult;

const VkDescriptorSetLayoutBinding myDescr=
iptorSetLayoutBinding[] =3D
{
    // binding to a single image descriptor
    {
        0,                                  =
    // binding
        VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // =
descriptorType
        1,                                  =
    // descriptorCount
        VK_SHADER_STAGE_FRAGMENT_BIT,           // =
stageFlags
        NULL                    =
                // pImmutableSamplers
    },

    // binding to an array of image descriptors
    {
        1,                                  =
    // binding
        VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // =
descriptorType
        12,                                 =
    // descriptorCount
        VK_SHADER_STAGE_FRAGMENT_BIT,           // =
stageFlags
        NULL                    =
                // pImmutableSamplers
    },

    // binding to a single uniform buffer descripto=
r
    {
        0,                                  =
    // binding
        VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,      // =
descriptorType
        1,                                  =
    // descriptorCount
        VK_SHADER_STAGE_FRAGMENT_BIT,           // =
stageFlags
        NULL                    =
                // pImmutableSamplers
    }
};

const VkDescriptorSetLayoutCreateInfo myDe=
scriptorSetLayoutCreateInfo[] =3D
{
    // Create info for first descriptor set with tw=
o descriptor bindings
    {
        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    // sType
        NULL,                   =
                                // pNext
        0,                                  =
                    // flags
        2,                                  =
                    // bindingCount
        &myDescriptorSetLayoutBinding[0]=
                        // pBindings
    },

    // Create info for second descriptor set with o=
ne descriptor binding
    {
        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    // sType
        NULL,                   =
                                // pNext
        0,                                  =
                    // flags
        1,                                  =
                    // bindingCount
        &myDescriptorSetLayoutBinding[2]=
                        // pBindings
    }
};

VkDescriptorSetLayout myDescriptorSetLayout[2];

//
// Create first descriptor set layout
//
myResult =3D vkCreateDescriptorSetLayout(
    myDevice,
    &myDescriptorSetLayoutCreateInfo[0],
    NULL,
    &myDescriptorSetLayout[0]);

//
// Create second descriptor set layout
//
myResult =3D vkCreateDescriptorSetLayout(
    myDevice,
    &myDescriptorSetLayoutCreateInfo[1],
    NULL,
    &myDescriptorSetLayout[1]);

To destroy a descriptor set layout, call:

void vkDestroyDescriptorSetLayout(
    VkDevice                                    device,
    VkDescriptorSetLayout                       descriptorSetLayout,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the descriptor s= et layout.

  • descriptorSetLayout is the descriptor set layout to destroy= .

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage (Implicit)
Host Synchronization
  • Host access to descriptorSetLayout must be externally synchronized

13.2.2. Pipeline Layouts

Access to descriptor sets from a pipeline is accomplished through a pipeline layout. Zero or more descriptor set layouts and zero or more push constant ranges are combined to form a pipeline layout object which describes the complete set of resources that can be accessed by = a pipeline. The pipeline layout represents a sequence of descriptor sets with each having a specific layout. This sequence of layouts is used to determine the interface between shader stages and shader resources. Each pipeline is created using a pipeline layout.

Pipeline layout objects are represented by VkPipelineLayout= handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkPipelineLayout)

To create a pipeline layout, call:

VkResult vkCreateP=
ipelineLayout(
    VkDevice                                    device,
    const VkPipelineLayoutCreateInfo*     =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkPipelineLayout*                           pPipelineLayout);
Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • p= CreateInfo must be a valid pointer= to a valid VkPipelineLayoutCreateInfo structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllo= cationCallbacks structure

  • pPipelineLayout must be a valid= pointer to a VkPipelineLayout handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkPipelineLayoutCreateInfo structure= is defined as:

typedef struct VkPipelineLayout=
CreateInfo {
    VkStructureType                 sType;
    const void*                     pNext;
    VkPipelineLayoutCreateFlags     flags;
    uint32_t                        setLayoutCount;
    const VkDescriptorSetLayout*    pSetLa=
youts;
    uint32_t                        pushConstantRangeCount;
    const VkPushConstantRange*      pPushC=
onstantRanges;
} VkPipelineLayoutCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • setLayoutCount is the number of descriptor sets included in= the pipeline layout.

  • pSetLayouts is a pointer to an array of VkDescriptorSetLayout objects.

  • pushConstantRangeCount is the number of push constant range= s included in the pipeline layout.

  • pPushConstantRanges is a pointer to an array of VkPushConstantRange structures defining a set of push constant ranges for use in a single pipeline layout. In addition to descriptor set layouts, a pipeline layout also describes how many push constants can be accessed b= y each stage of the pipeline.

    Note

    Push constants represent a high speed path to modify constant data in pipelines that is expected to outperform memory-backed resource updates.

Valid Usage
  • setLayoutCount must be less = than or equal to VkPhysicalDeviceLimits::maxBoundDescriptorSets

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_SAMPLER<= /code> and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible to any gi= ven shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSamplers

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER and VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC accessible to any gi= ven shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorUniformBuff= ers

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER and VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC accessible to any gi= ven shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorStorageBuff= ers

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible to any give= n shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSampledImag= es

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible to any give= n shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorStorageImag= es

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT accessible to any given sh= ader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorInputAttach= ments

  • The total number of descriptors with a descriptorType of VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible to any gi= ven shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxPerS= tageDescriptorUpdateAfterBindSamplers

  • The total number of descriptors with a descriptorType of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER and VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC accessible to any gi= ven shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxPerS= tageDescriptorUpdateAfterBindUniformBuffers

  • The total number of descriptors with a descriptorType of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER and VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC accessible to any gi= ven shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxPerS= tageDescriptorUpdateAfterBindStorageBuffers

  • The total number of descriptors with a descriptorType of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible to any give= n shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxPerS= tageDescriptorUpdateAfterBindSampledImages

  • The total number of descriptors with a descriptorType of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible to any give= n shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxPerS= tageDescriptorUpdateAfterBindStorageImages

  • The total number of descriptors with a descriptorType of VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT accessible to any given sh= ader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxPerS= tageDescriptorUpdateAfterBindInputAttachments

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_SAMPLER<= /code> and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible across al= l shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetSamplers<= /p>

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetUniformBuffers

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC accessible across al= l shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetUniformBuffersDy= namic

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetStorageBuffers

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC accessible across al= l shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetStorageBuffersDy= namic

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetSampledImages

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetStorageImages

  • The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set with a descriptorType of VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT accessible across all shad= er stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetInputAttachments=

  • The total number of descriptors of the type VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible across al= l shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxDesc= riptorSetUpdateAfterBindSamplers

  • The total number of descriptors of the type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxDesc= riptorSetUpdateAfterBindUniformBuffers

  • The total number of descriptors of the type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC accessible across al= l shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxDesc= riptorSetUpdateAfterBindUniformBuffersDynamic

  • The total number of descriptors of the type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxDesc= riptorSetUpdateAfterBindStorageBuffers

  • The total number of descriptors of the type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC accessible across al= l shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxDesc= riptorSetUpdateAfterBindStorageBuffersDynamic

  • The total number of descriptors of the type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxDesc= riptorSetUpdateAfterBindSampledImages

  • The total number of descriptors of the type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxDesc= riptorSetUpdateAfterBindStorageImages

  • The total number of descriptors of the type VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT accessible across all shad= er stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceDescriptorIndexingPropertiesEXT::maxDesc= riptorSetUpdateAfterBindInputAttachments

  • Any two elements of pPushConstantRanges must not include the same stage in stageFlags

  • pSetLayouts must not contain= more than one descriptor set layout that was created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR set

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PIP= ELINE_LAYOUT_CREATE_INFO

  • pNext must be NULL

  • f= lags must be 0

  • If = setLayoutCount is not 0, pSetLayouts= must be a valid pointer to an array of <= code>setLayoutCount valid VkDescriptorSetLayout handles=

  • = If pushConstantRangeCount is not 0, pP= ushConstantRanges must be a valid = pointer to an array of pushConstantRangeCount valid VkPu= shConstantRange structures

typedef VkFlags VkPipelineLayoutCreateFlags;

VkPipelineLayoutCreateFlags is a bitmask type for setting a= mask, but is currently reserved for future use.

The VkPushConstantRange structure is defined as:

typedef struct VkPushConstantRa=
nge {
    VkShaderStageFlags    stageFlags;
    uint32_t              offset;
    uint32_t              size;
} VkPushConstantRange;
  • stageFlags is a set of stage flags describing the shader st= ages that will access a range of push constants. If a particular stage is not included in the range, then accessing members of that range of push constants from the corresponding shader stage will result in undefined data being read.

  • offset and size are the start offset and size,= respectively, consumed by the range. Both offset and size are in units of bytes and must be a multiple of 4. The layout of the push constant variables is specified in the shader.

Valid Usage
  • offset must be less than VkPhysicalDeviceLimits::maxPushConstantsSize

  • offset must be a multiple of= 4

  • size must be greater than 0

  • size must be a multiple of <= code>4

  • size must be less than or eq= ual to VkPhysicalDeviceLimits::maxPushConstantsSize minu= s offset

Valid Usage (Implicit)

Once created, pipeline layouts are used as part of pipeline creation (se= e Pipelines), as part of binding descriptor sets (see Descriptor Set Binding), and as part of setting push constants (see Push Constant Updates). Pipeline creation accepts a pipeline layout as input, and the layout may be used to map (set, binding, arrayElement) tuples to implementation resources or memory locations within a descriptor set. The assignment of implementation resources depends only on the bindings defined in the descriptor sets that comprise the pipeline layout, and not o= n any shader source.

All resource variables statically used in all sha= ders in a pipeline must be declared with a (se= t,binding,arrayElement) that exists in the corresponding descriptor set layout and is of an appropriate descriptor type and includes the set of shader stages it is used by in stageFlags. The pipeline layout can include entries t= hat are not used by a particular pipeline, or that are dead-code eliminated from any of the shaders. The pipeline layout allows the application to provide a consistent set of bindings across multiple pipeline compiles, which enables those pipelines t= o be compiled in a way that the implementation may cheaply switch pipelines without reprogramming the bindings.

Similarly, the push constant block declared in each shader (if present) must only place variables at offsets that= are each included in a push constant range with stageFlags including the bit corresponding= to the shader stage that uses it. The pipeline layout can include ranges or= portions of ranges that are not used by a particular pipeline, or for which the variables have been dead-code eliminated from any of the shaders.

There is a limit on the total number of resources of each type that can be included in bindings in all descriptor set layouts in a pipeline layout as shown in Pipeline Layout Resource Limits. The =E2=80=9CTotal Resources Available=E2=80=9D column gives the limit on t= he number of each type of resource that can be include= d in bindings in all descriptor sets in the pipeline layout. Some resource types count against multiple limits. Additionally, there are limits on the total number of each type of resource that can be used in any pipeline stage as= described in Shader Resource Limits.

Table 17. Pipeline Layout Resource Limits
Total Resources Available Resource Types

maxDescriptorSetSamplers or maxDescriptorSetUpdateAfterBindSamplers

sam= pler

com= bined image sampler

maxDescriptorSetSampledImages or maxDescriptorSetUpdateAfterBindSampledImages

sam= pled image

com= bined image sampler

uni= form texel buffer

maxDescriptorSetStorageImages or maxDescriptorSetUpdateAfterBindStorageImages

sto= rage image

sto= rage texel buffer

maxDescriptorSetUniformBuffers or maxDescriptorSetUpdateAfterBindUniformBuffers

uni= form buffer

uni= form buffer dynamic

maxDescriptorSetUniformBuffersDynamic or maxDescriptorSetUpdateAfterBindUniformBuffersDynamic

uni= form buffer dynamic

maxDescriptorSetStorageBuffers or maxDescriptorSetUpdateAfterBindStorageBuffers

sto= rage buffer

sto= rage buffer dynamic

maxDescriptorSetStorageBuffersDynamic or maxDescriptorSetUpdateAfterBindStorageBuffersDynamic

sto= rage buffer dynamic

maxDescriptorSetInputAttachments or maxDescriptorSetUpdateAfterBindInputAttachments

inp= ut attachment

To destroy a pipeline layout, call:

void vkDestroyPipelineLayout(
    VkDevice                                    device,
    VkPipelineLayout                            pipelineLayout,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the pipeline lay= out.

  • pipelineLayout is the pipeline layout to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • If VkAllocationCallbacks were provided when pipelineLayo= ut was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when pipelineLayout was created, pAllocator must be NULL

  • pipelineLayout must not have= been passed to any vkCmd* command for any command buffers that are still in the recording state when vkDestroyPipelineLayout is called

Valid Usage (Implicit)
  • devic= e must be a valid VkDevice handle

  • If = pipelineLayout is not VK_NULL_HANDLE, pipelineLayout must be a valid <= code>VkPipelineLayout handle

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAll= ocationCallbacks structure

  • If pipelineLayout is a valid handle, it mus= t have been created, allocated, or retrieved from device

Host Synchronization
  • Host access to pipelineLayout must= be externally synchronized

Pipeline Layout Compatibility

Two pipeline layouts are defined to be =E2=80=9Ccompatible for push constants=E2=80=9D if they were cre= ated with identical push constant ranges. Two pipeline layouts are defined to be =E2=80=9Ccompatible for set N=E2=80= =9D if they were created with identically defined descriptor set layouts for sets z= ero through N, and if they were created with identical push constant ranges.

When binding a descriptor set (see Descriptor Se= t Binding) to set number N, if the previously bound descriptor sets for s= ets zero through N-1 were all bound using compatible pipeline layouts, then performing this binding does not disturb any of the lower numbered sets. If, additionally, the previous bound descriptor set for set N was bound using a pipeline layout compatible for set N, then the bindings in sets numbered greater than N are also not disturbed.

Similarly, when binding a pipeline, the pipeline can correctly access any previously bound descriptor sets which were bound with compatible pipeline layouts, as long as all lower numbered sets were also bound with compatible layouts.

Layout compatibility means that descriptor sets can be bound to a command buffer for use by any pipeline created with a compatible pipeline layout, and without having bound a particular pipeline first. It also means that descriptor sets can re= main valid across a pipeline change, and the same resources will be accessible to the newly bound pipeline.

Implementor=E2=80=99s Note

A consequence of layout compatibility is that when the implementation compiles a pipeline layout and maps pipeline resources to implementation resources, the mechanism for set N should= only be a function of sets [0..N].

Note

Place the least frequently changing descriptor sets near the start of th= e pipeline layout, and place the descriptor sets representing the most frequently changing resources near the end. When pipelines are switched, only the descriptor set bindings that have bee= n invalidated will need to be updated and the remainder of the descriptor set bindings will remain in place.

The maximum number of descriptor sets that can<= /strong> be bound to a pipeline layout is queried from physical device properties (see maxBoundDescriptorSets in Limits).

API example
const VkDescriptorSetLayout layouts[] =3D { layout1, layout2=
 };

const VkPushConstantRange ranges[] =3D
{
    {
        VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,    // =
stageFlags
        0,                                  =
    // offset
        4                                   =
    // size
    },

    {
        VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,  // =
stageFlags
        4,                                  =
    // offset
        4                                   =
    // size
    },
};

const VkPipelineLayoutCreateInfo createInf=
o =3D
{
    VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // sType
    NULL,                       =
                    // pNext
    0,                                      =
        // flags
    2,                                      =
        // setLayoutCount
    layouts,                                        // pSetLayouts
    2,                                      =
        // pushConstantRangeCount
    ranges                                          // pPushConstantRanges
};

VkPipelineLayout myPipelineLayout;
myResult =3D vkCreatePipelineLayout(
    myDevice,
    &createInfo,
    NULL,
    &myPipelineLayout);

13.2.3. Allocation of Descriptor Sets<= /h4>

A descriptor pool maintains a pool of descriptors, from which d= escriptor sets are allocated. Descriptor pools are externally synchronized, meaning that the application must not allocate and/or free descriptor = sets from the same pool in multiple threads simultaneously.

Descriptor pools are represented by VkDescriptorPool handle= s:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDescriptorPool)

To create a descriptor pool object, call:

VkResult vkCreateD=
escriptorPool(
    VkDevice                                    device,
    const VkDescriptorPoolCreateInfo*     =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDescriptorPool*                           pDescriptorPool);
  • device is the logical device that creates the descriptor po= ol.

  • pCreateInfo is a pointer to an instance of the VkDescriptorPoolCreateInfo structure specif= ying the state of the descriptor pool object.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pDescriptorPool points to a VkDescriptorP= ool handle in which the resulting descriptor pool object is returned.

pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

The created descriptor pool is returned in pDescriptorPool.=

Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • p= CreateInfo must be a valid pointer= to a valid VkDescriptorPoolCreateInfo structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllo= cationCallbacks structure

  • pDescriptorPool must be a valid= pointer to a VkDescriptorPool handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_FRAGMENTATION_EXT

Additional information about the pool is passed in an instance of the VkDescriptorPoolCreateInfo structure:

typedef struct VkDescriptorPool=
CreateInfo {
    VkStructureType                sType;
    const void*                    pNext;
    VkDescriptorPoolCreateFlags    flags;
    uint32_t                       maxSets;
    uint32_t                       poolSizeCount;
    const VkDescriptorPoolSize*    pPoolSi=
zes;
} VkDescriptorPoolCreateInfo;

Fragmentation of a descriptor pool is possible and may lead to descriptor set allocation failures. A failure due to fragmentation is defined as failing a descriptor set allocation despite the sum of all outstanding descriptor set allocations from the pool plus the requested allocation requiring no more than the tota= l number of descriptors requested at pool creation. Implementations provide certain guarantees of when fragmentation must not cause allocation failure, as described below.

If a descriptor pool has not had any descriptor sets freed since it was created or most recently reset then fragmentation = must not cause an allocation failure (note that this is always the case for a pool created without the VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = bit set). Additionally, if all sets allocated from the pool since it was created or most recently reset use the same number of descriptors (of each type) and the requested allocation also uses that same number of descriptors (of each type), then fragmentation must not cause = an allocation failure.

If an allocation failure occurs due to fragmentation, an application can create an additional descriptor pool to perform further descriptor set allocations.

If flags has the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT bit set, descriptor pool creation may fail with th= e error VK_ERROR_FRAGMENTATION_EXT if the total number of descriptors = across all pools (including this one) created with this bit set exceeds maxUpdateAfterBindDescriptorsInAllPools, or if fragmentation o= f the underlying hardware resources occurs.

Valid Usage
  • maxSets must be greater than= 0

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DES= CRIPTOR_POOL_CREATE_INFO

  • pNext must be NULL

  • fla= gs must be a valid combination of = VkDescriptorPoolCreateFlagBits values

  • pPoolSizes must be a valid point= er to an array of poolSizeCount valid VkDescriptorPoolSi= ze structures

  • = poolSizeCount must be great= er than 0

Bits which can be set in VkDescriptorPoolCreateInfo::flags to enable operations on a descriptor pool are:

typedef enum VkDescriptorPoolCr=
eateFlagBits {
    VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT =3D 0x00000001,
    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT =3D 0x00000002,
} VkDescriptorPoolCreateFlagBits;
  • VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT specifies= that descriptor sets can return their individu= al allocations to the pool, i.e. all of vkAllocateDescriptorSets, vkFreeDescriptorSets, and vkResetDescriptorPool are allowed. Otherwise, descriptor sets allocated from the pool must not be individually freed back to the pool, i.e. only vkAllocateDescriptorSets and vkResetDescriptorPool are allowed.

  • VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT specifi= es that descriptor sets allocated from this pool can include bindings with the VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT bit set. It is valid to allocate descriptor sets that have bindings that do not set the VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT bit fr= om a pool that has VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT set.

typedef VkFlags VkDescriptorPoolCreateFlags;

VkDescriptorPoolCreateFlags is a bitmask type for setting a= mask of zero or more VkDescriptorPoolCreateFlagBits= .

The VkDescriptorPoolSize structure is defined as:

typedef struct VkDescriptorPool=
Size {
    VkDescriptorType    type;
    uint32_t            descriptorCount;
} VkDescriptorPoolSize;
  • type is the type of descriptor.

  • descriptorCount is the number of descriptors of that type t= o allocate.

Valid Usage
  • descriptorCount must be grea= ter than 0

Valid Usage (Implicit)

To destroy a descriptor pool, call:

void vkDestroyDescriptorPool(
    VkDevice                                    device,
    VkDescriptorPool                            descriptorPool,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the descriptor p= ool.

  • descriptorPool is the descriptor pool to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

When a pool is destroyed, all descriptor sets allocated from the pool ar= e implicitly freed and become invalid. Descriptor sets allocated from a given pool do not need to be freed before destroying that descriptor pool.

Valid Usage
  • All submitted commands that refer to descriptorPool (via any allocated descriptor sets) must have comp= leted execution

  • If VkAllocationCallbacks were provided when descriptorPo= ol was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when descriptorPool was created, pAllocator must be NULL

Valid Usage (Implicit)
  • devic= e must be a valid VkDevice handle

  • If = descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid <= code>VkDescriptorPool handle

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAll= ocationCallbacks structure

  • If descriptorPool is a valid handle, it mus= t have been created, allocated, or retrieved from device

Host Synchronization
  • Host access to descriptorPool must= be externally synchronized

Descriptor sets are allocated from descriptor pool objects, and are represented by VkDescriptorSet handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDescriptorSet)

To allocate descriptor sets from a descriptor pool, call:

VkResult vkAllocat=
eDescriptorSets(
    VkDevice                                    device,
    const VkDescriptorSetAllocateInfo*    =
      pAllocateInfo,
    VkDescriptorSet*                            pDescriptorSets);

When a descriptor set is allocated, the initial state is largely uninitialized and all descriptors are undefined. However, the descriptor set can be bound = in a command buffer without causing errors or exceptions. For descriptor set bindings created with the VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT bit set, all des= criptors in that binding that are dynamically used must have been populated before the descriptor set is consumed. For descriptor set bindings created without the VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT bit set, all des= criptors in that binding that are statically used must have been populated before the descriptor set is consumed. Entries that are not used by a pipeline can have uninitialized descriptors or descriptors of resources that have been destroyed, and executing a draw or dispatch with such a descriptor set bound does not cause undefined behavior. This means applications need not populate unused entries with dummy descriptors.

If a call to vkAllocateDescriptorSets would cause the total= number of descriptor sets allocated from the pool to exceed the value of VkDescriptorPoolCreateInfo::maxSets used to create pAllocateInfo=E2=86=92descriptorPool, then the al= location may fail due to lack of space in the descriptor pool. Similarly, the allocation may fail due to= lack of space if the call to vkAllocateDescriptorSets would cause the number of any given descriptor type to exceed the sum of all the descriptorCount m= embers of each element of VkDescriptorPoolCreateInfo::pPoolSizes with a member equal to that type. If the allocation fails due to no more space in the descriptor pool, and no= t because of system or device memory exhaustion, then VK_ERROR_OUT_OF_POOL_MEMORY must be returned.

Valid Usage (Implicit)
  • devi= ce must be a valid VkDevice<= /code> handle

  • pAllocateInfo must be a valid p= ointer to a valid VkDescriptorSetAllocateInfo structure

  • <= code>pDescriptorSets must be a val= id pointer to an array of pAllocateInfo::descriptorSetCount VkDescriptorSet handles

Host Synchronization
  • Host access to pAllocateInfo::descriptorPool must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_FRAGMENTED_POOL

  • VK_ERROR_OUT_OF_POOL_MEMORY

The VkDescriptorSetAllocateInfo structure is defined as:

typedef struct VkDescriptorSetA=
llocateInfo {
    VkStructureType                 sType;
    const void*                     pNext;
    VkDescriptorPool                descriptorPool;
    uint32_t                        descriptorSetCount;
    const VkDescriptorSetLayout*    pSetLa=
youts;
} VkDescriptorSetAllocateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • descriptorPool is the pool which the sets will be allocated= from.

  • descriptorSetCount determines the number of descriptor sets= to be allocated from the pool.

  • pSetLayouts is an array of descriptor set layouts, with eac= h member specifying how the corresponding descriptor set is allocated.

Valid Usage
  • Each element of pSetLayouts must not have been created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR set

  • If any element of pSetLayouts was created with the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set, descriptorPool must hav= e been created with the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT flag set

Valid Usage (Implicit)
  • sType<= /code> must be VK_STRUCTURE_TYPE_DE= SCRIPTOR_SET_ALLOCATE_INFO

  • pNext<= /code> must be NULL or a poi= nter to a valid instance of VkDescriptorSetVariableDescriptorCountAllocateInfoEXT

  • = descriptorPool must be a va= lid VkDescriptorPool handle

  • pSetLayouts must be a valid po= inter to an array of descriptorSetCount valid VkDescript= orSetLayout handles

  • descriptorSetCount must be greater than 0

  • Both of descriptorPool, and the elements of pSetLayouts must have been created, allocated, or retriev= ed from the same VkDevice

If the pNext chain of a VkDesc= riptorSetAllocateInfo structure includes a VkDescriptorSetVariableDescriptorCountAllocateInfoEXT structure, then that structure includes an array of descriptor counts for variable descriptor count bindings, one for each descriptor set being allocated.

The VkDescriptorSetVariableDescriptorCountAllocateInfoEXT s= tructure is defined as:

typedef struct VkDescriptorSetV=
ariableDescriptorCountAllocateInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           descriptorSetCount;
    const uint32_t*    pDescriptorCounts;
} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • descriptorSetCount is zero or the number of elements in pDescriptorCounts.

  • pDescriptorCounts is an array of descriptor counts, with ea= ch member specifying the number of descriptors in a variable descriptor count binding in the corresponding descriptor set being allocated.

If descriptorSetCount is zero or this structure is not incl= uded in the pNext chain, then the variable lengths are considered to be ze= ro. Otherwise, pDescriptorCounts[i] is the number of descriptors i= n the variable count descriptor binding in the corresponding descriptor set layout. If VkDescriptorSetAllocateInfo::pSet= Layouts[i] does not include a variable count descriptor binding, then pDescriptorCounts[i]= is ignored.

Valid Usage
  • If descriptorSetCount is not zero, descriptorSetCount must equal VkDescriptorSetAllocateInfo::d= escriptorSetCount

  • If VkDescriptorSetAllocateInfo::pSet= Layouts[i] has a variable descriptor count binding, then pDescriptorCounts[i] <= strong class=3D"purple">must be less than or equal to the descriptor count specified for that binding when the descriptor set layout was created.

Valid Usage (Implicit)
  • sType must be = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_I= NFO_EXT

  • If descriptorSetCount is not 0, pDescriptorCounts must be a valid pointer to an array of descriptorSetCount <= code>uint32_t values

To free allocated descriptor sets, call:

VkResult vkFreeDes=
criptorSets(
    VkDevice                                    device,
    VkDescriptorPool                            descriptorPool,
    uint32_t                                    descriptorSetCount,
    const VkDescriptorSet*                =
      pDescriptorSets);
  • device is the logical device that owns the descriptor pool.=

  • descriptorPool is the descriptor pool from which the descri= ptor sets were allocated.

  • descriptorSetCount is the number of elements in the pDescriptorSets array.

  • pDescriptorSets is an array of handles to = VkDescriptorSet objects.

After a successful call to vkFreeDescriptorSets, all descri= ptor sets in pDescriptorSets are invalid.

Valid Usage
  • All submitted commands that refer to any element of pDescriptorSets must have co= mpleted execution

  • pDescriptorSets must be a va= lid pointer to an array of descriptorSetCount VkDescriptorSet handles, each = element of which must either be a valid handle or VK_NULL_HANDLE

  • Each valid handle in pDescriptorSets = must have been allocated from descriptorPool

  • descriptorPool must have bee= n created with the VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT flag

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • = descriptorPool must be a valid VkDescriptorPool handle

  • = descriptorSetCount must be g= reater than 0

  • des= criptorPool must have been created= , allocated, or retrieved from device

  • Each ele= ment of pDescriptorSets that is a valid handle must have been created, allocated, or retrieved from <= code>descriptorPool

Host Synchronization
  • Host access to descriptorPool must= be externally synchronized

  • Host access to each member of pDescriptorSets must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

To return all descriptor sets allocated from a given pool to the pool, rather than freeing individual descriptor sets, call:

VkResult vkResetDe=
scriptorPool(
    VkDevice                                    device,
    VkDescriptorPool                            descriptorPool,
    VkDescriptorPoolResetFlags                  flags);
  • device is the logical device that owns the descriptor pool.=

  • descriptorPool is the descriptor pool to be reset.

  • flags is reserved for future use.

Resetting a descriptor pool recycles all of the resources from all of th= e descriptor sets allocated from the descriptor pool back to the descriptor pool, and the descriptor sets are implicitly freed.

Valid Usage
  • All uses of descriptorPool (via any allocated descriptor sets) must have completed execution

Valid Usage (Implicit)
  • device<= /code> must be a valid VkDevice handle

  • descriptorPool must be a valid VkDescriptorPool handle

  • flags<= /code> must be 0

  • de= scriptorPool must have been create= d, allocated, or retrieved from device

Host Synchronization
  • Host access to descriptorPool must= be externally synchronized

  • Host access to any VkDescriptorSet objects allocated from <= code>descriptorPool must be extern= ally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

typedef VkFlags VkDescriptorPoolResetFlags;

VkDescriptorPoolResetFlags is a bitmask type for setting a = mask, but is currently reserved for future use.

13.2.4. Descriptor Set Updates

Once allocated, descriptor sets can be= updated with a combination of write and copy operations. To update descriptor sets, call:

void vkUpdateDescriptorSets(
    VkDevice                                    device,
    uint32_t                                    descriptorWriteCount,
    const VkWriteDescriptorSet*           =
      pDescriptorWrites,
    uint32_t                                    descriptorCopyCount,
    const VkCopyDescriptorSet*            =
      pDescriptorCopies);
  • device is the logical device that updates the descriptor se= ts.

  • descriptorWriteCount is the number of elements in the pDescriptorWrites array.

  • pDescriptorWrites is a pointer to an array of VkWriteDescriptorSet structures describing the de= scriptor sets to write to.

  • descriptorCopyCount is the number of elements in the pDescriptorCopies array.

  • pDescriptorCopies is a pointer to an array of VkCopyDescriptorSet structures describing the desc= riptor sets to copy between.

The operations described by pDescriptorWrites are performed= first, followed by the operations described by pDescriptorCopies. Within each array, the operations are performed in the order they appear in the array.

Each element in the pDescriptorWrites array describes an op= eration updating the descriptor set using descriptors for resources specified in th= e structure.

Each element in the pDescriptorCopies array is a VkCopyDescriptorSet structure describing an operat= ion copying descriptors between sets.

If the dstSet member of any element of pDescriptorWri= tes or pDescriptorCopies is bound, accessed, or modified by any comma= nd that was recorded to a command buffer which is currently in the recording or executable state, and any of the descriptor bindings that are updated were not created with the VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT or VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT bits= set, that command buffer becomes invalid.

Valid Usage
  • Descriptor bindings updated by this command which were created without the VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT or VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT bits= set must not be used by any command that was = recorded to a command buffer which is in the pending state.

Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • I= f descriptorWriteCount is not 0, pDescripto= rWrites must be a valid pointer to= an array of descriptorWriteCount valid VkWriteDescripto= rSet structures

  • I= f descriptorCopyCount is not 0, pDescriptor= Copies must be a valid pointer to = an array of descriptorCopyCount valid VkCopyDescriptorSe= t structures

Host Synchronization
  • Host access to pDescriptorWrites[].dstSet must be externally synchronized

  • Host access to pDescriptorCopies[].dstSet must be externally synchronized

The VkWriteDescriptorSet structure is defined as:

typedef struct VkWriteDescripto=
rSet {
    VkStructureType                  sType;
    const void*                      pNext;
    VkDescriptorSet                  dstSet;
    uint32_t                         dstBinding;
    uint32_t                         dstArrayElement;
    uint32_t                         descriptorCount;
    VkDescriptorType                 descriptorType;
    const VkDescriptorImageInfo*     pImag=
eInfo;
    const VkDescriptorBufferInfo*    pBuff=
erInfo;
    const VkBufferView*              pTexe=
lBufferView;
} VkWriteDescriptorSet;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • dstSet is the destination descriptor set to update.

  • dstBinding is the descriptor binding within that set.

  • dstArrayElement is the starting element in that array.

  • descriptorCount is the number of descriptors to update (the= number of elements in pImageInfo, pBufferInfo, or pTexelBufferView).

  • descriptorType is a VkDescriptorType = specifying the type of each descriptor in pImageInfo, pBufferInfo, or pTexelBufferView, as described below. It must be the same type as that specifie= d in VkDescriptorSetLayoutBinding for dstSet at = dstBinding. The type of the descriptor also controls which array the descriptors are taken from.

  • pImageInfo points to an array of VkD= escriptorImageInfo structures or is ignored, as described below.

  • pBufferInfo points to an array of V= kDescriptorBufferInfo structures or is ignored, as described below.

  • pTexelBufferView points to an array of VkBuff= erView handles as described in the Buffer Views section or is ignored, as described below.

Only one of pImageInfo, pBufferInfo, or = pTexelBufferView members is used according to the descriptor type specified in the descriptorType member of the containing VkWriteDescripto= rSet structure, as specified below.

If the dstBinding has fewer than descriptorCount array elements remaining starting from dstArrayElement, then the remainder wi= ll be used to update the subsequent binding - dstBinding= +1 starting at array element zero. If a binding has a descriptorCount of zero, it is skipped. This behavior applies recursively, with the update affecting consecutive bindings as needed to update all descriptorCount descriptors.<= /p>

Valid Usage
  • dstBinding must be less than= or equal to the maximum value of binding of all VkDescriptorSetLa= youtBinding structures specified when dstSet=E2=80=99s descriptor set layout was crea= ted

  • dstBinding must be a binding= with a non-zero descriptorCount

  • All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a descriptorCount of zero, must have identical descriptorType and stageFlags.

  • All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a descriptorCount of zero, must all either use immutable samplers or must all= not use immutable samplers.

  • descriptorType must match th= e type of dstBinding within dstSet

  • dstSet must be a valid VkDescriptorSet handle

  • The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutiv= e bindings, as described by consecutive b= inding updates

  • If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pImageInfo <= strong class=3D"purple">must be a valid pointer to an array of descriptorCount valid VkDescriptorImageInfo structures

  • If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BU= FFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, pTexelBuffer= View must be a valid pointer to an array of descriptorCount valid VkBufferView handles

  • If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a valid pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures

  • If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER o= r VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and dstSet was not allocated with a layout that included immutable samplers for dstBinding with descriptorType, the sampler= member of each element of pImageInfo must be a valid VkSampler object

  • If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout members of each element of pImageInfo= must be a valid VkImageView and VkImageLayout, respec= tively

  • If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, then the imageView member of each pImageInfo element <= strong class=3D"purple">must have been created without a VkSamplerYcbcrConversionInfo structure = in its pNext chain

  • If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and if any element = of pImageInfo has a imageView member that was create= d with a VkSamplerYcbcrConversionInfo structure in its pNext chain, then dstSet must have been a= llocated with a layout that included immutable samplers for dstBinding

  • If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and dstSet was allocated with a layout that included immutable samplers for dstBinding, then the imageView member of each ele= ment of pImageInfo which corresponds to a immutable sampler that enabl= es sampler Y=E2=80=99CBCR con= version must have been created with a VkSamplerYcbcrConversionInfo structure in = its pNext chain with an identically defined VkSamplerYcbcrConversionInfo to the corresponding immutable sampler

  • If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, for each descriptor that will be accessed via load or store operations the imageLayout member for corresponding elements of pImageI= nfo must be VK_IMAGE_LAYOUT_GENERAL

  • If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the offset member of each element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment<= /code>

  • If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the offset member of each element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment<= /code>

  • If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, and the buffe= r member of any element of pBufferInfo is the handle of a non-sp= arse buffer, then that buffer must be bound co= mpletely and contiguously to a single VkDeviceMemory object

  • If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the buffer member of each element of pBufferInfo must have been created with VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set

  • If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the buffer member of each element of pBufferInfo must have been created with VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set

  • If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the range member of each element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, = must be less than or equal to VkPhysicalDeviceLimits::maxUniformBufferRange

  • If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the range member of each element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, = must be less than or equal to VkPhysicalDeviceLimits::maxStorageBufferRange

  • If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, the VkBuffer that each element of pTexelBufferView was created from must have been created with VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set

  • If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, the VkBuffer that each element of pTexelBufferView was created from must have been created with VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set

  • If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView member of each element of pImageInfo must have been created with the identity swizzle

  • If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, the imageView= member of each element of pImageInfo = must have been created with VK_IMAGE_USAGE_SAMPLED_BIT set

  • If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, the imageLayo= ut member of each element of pImageInfo = must be VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

  • If descriptorType is VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT= , the imageView member of each element of pImageInfo must have been created with VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set=

  • If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, the imageView member of each element of pImageInfo must have been created with VK_IMAGE_USAGE_STORAGE_BIT set

  • All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a descriptorCount of zero, must have identical VkDescriptorBindingFlagBitsEXT.

Valid Usage (Implicit)
  • sType = must be VK_STRUCTURE_TYPE_WRITE_DES= CRIPTOR_SET

  • pNext = must be NULL

  • = descriptorType must be a valid VkDescriptorType value

  • descriptorCount must be greater= than 0

  • Both of dstS= et, and the elements of pTexelBufferView that are valid= handles must have been created, allocate= d, or retrieved from the same VkDevice

The type of descriptors in a descriptor set is specified by VkWriteDescriptorSet::descriptorType= , which must be one of the values:

typedef enum VkDescriptorType {
    VK_DESCRIPTOR_TYPE_SAMPLER =3D 0,
    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER =3D 1=
,
    VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE =3D 2,
    VK_DESCRIPTOR_TYPE_STORAGE_IMAGE =3D 3,
    VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER =3D 4,
    VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER =3D 5,
    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER =3D 6,
    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER =3D 7,
    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC =3D 8=
,
    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC =3D 9=
,
    VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT =3D 10,
} VkDescriptorType;

When a descriptor set is updated via elements of V= kWriteDescriptorSet, members of pImageInfo, pBufferInfo and pTex= elBufferView are only accessed by the implementation when they correspond to descriptor type being defined - otherwise they are ignored. The members accessed are as follows for each descriptor type:

  • For VK_DESCRIPTOR_TYPE_SAMPLER, only the sample member of each element of VkWriteDescriptorSet::pImag= eInfo is accessed.

  • For VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, only the imageView<= /code> and imageLayout members of each element of VkWriteDescriptorSet::pImageInfo are= accessed.

  • For VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, all members = of each element of VkWriteDescriptorSet::pImageInfo= are accessed.

  • For VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, all members of each element of VkWriteDescriptorSet::pBufferInf= o are accessed.

  • For VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, each element of VkWriteDescriptorSet::pTexelBufferView is accessed.

The VkDescriptorBufferInfo structure is defined as:

typedef struct VkDescriptorBuff=
erInfo {
    VkBuffer        buffer;
    VkDeviceSize    offset;
    VkDeviceSize    range;
} VkDescriptorBufferInfo;
  • buffer is the buffer resource.

  • offset is the offset in bytes from the start of buffe= r. Access to buffer memory via this descriptor uses addressing that is relative to this starting offset.

  • range is the size in bytes that is used for this descriptor update, or VK_WHOLE_SIZE to use the range from offset to the end of the buffer.

Note

When setting range to VK_WHOLE_SIZE, the effec= tive range must not be larger than the maximum range for the descriptor type (maxUniformBufferRange or maxStorageBufferRange). This means that VK_WHOLE_SIZE is not typically useful in the c= ommon case where uniform buffer descriptors are suballocated from a buffer that i= s much larger than maxUniformBufferRange.

For VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC and VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC descriptor types, offset is the base offset from which the dynamic offset is app= lied and range is the static size used for all dynamic offsets.

Valid Usage
  • offset must be less than the= size of buffer

  • If range is not equal to VK_WHOLE_SIZE, ran= ge must be greater than 0

  • If range is not equal to VK_WHOLE_SIZE, ran= ge must be less than or equal to the size of buffer minus offset

Valid Usage (Implicit)
  • buffer= must be a valid VkBuffer handle

The VkDescriptorImageInfo structure is defined as:

typedef struct VkDescriptorImag=
eInfo {
    VkSampler        sampler;
    VkImageView      imageView;
    VkImageLayout    imageLayout;
} VkDescriptorImageInfo;
  • sampler is a sampler handle, and is used in descriptor upda= tes for types VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER if the binding being updated does not use immutable samplers.

  • imageView is an image view handle, and is used in descripto= r updates for types VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT.

  • imageLayout is the layout that the image subresources acces= sible from imageView will be in at the time this descriptor is acces= sed. imageLayout is used in descriptor updates for types VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT.

Members of VkDescriptorImageInfo that are not used in an up= date (as described above) are ignored.

Valid Usage
  • imageView must not be 2D or = 2D array image view created from a 3D image

  • If imageView is created from a depth/stencil image, the aspectMask used to create the imageView must include either VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT= but not both.

  • imageLayout must match the a= ctual VkImageLayout of each subresource accessible from imageView at the time this descrip= tor is accessed

  • If sampler is used and the VkFormat of the image= is a multi-planar format, the image must have been crea= ted with VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, and the aspectMask of the imageView must be = VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT or (for three-plane formats only) VK_IMAGE_ASPECT_PLANE_2_BIT

Valid Usage (Implicit)
  • Both of ima= geView, and sampler that are valid handles must have been created, allocated, or retrieved from = the same VkDevice

The VkCopyDescriptorSet structure is defined as:

typedef struct VkCopyDescriptor=
Set {
    VkStructureType    sType;
    const void*        pNext;
    VkDescriptorSet    srcSet;
    uint32_t           srcBinding;
    uint32_t           srcArrayElement;
    VkDescriptorSet    dstSet;
    uint32_t           dstBinding;
    uint32_t           dstArrayElement;
    uint32_t           descriptorCount;
} VkCopyDescriptorSet;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • srcSet, srcBinding, and srcArrayElement<= /code> are the source set, binding, and array element, respectively.

  • dstSet, dstBinding, and dstArrayElement<= /code> are the destination set, binding, and array element, respectively.

  • descriptorCount is the number of descriptors to copy from t= he source to destination. If descriptorCount is greater than the number of remaining arr= ay elements in the source or destination binding, those affect consecutive bindings in a manner similar to VkWriteDescriptorSet<= /a> above.

Valid Usage
  • srcBinding must be a valid b= inding within srcSet

  • The sum of srcArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by srcBinding, and all applicable consecutiv= e bindings, as described by consecutive b= inding updates

  • dstBinding must be a valid b= inding within dstSet

  • The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutiv= e bindings, as described by consecutive b= inding updates

  • If srcSet is equal to dstSet, then the source and destination ranges of descriptors must no= t overlap, where the ranges may include array elements from consecuti= ve bindings as described by consecutive binding updates

  • If srcSet=E2=80=99s layout was created with the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT flag set, then dstSet=E2=80=99s layout must also have been created with the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT flag set

  • If srcSet=E2=80=99s layout was created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT flag set, then dstSet=E2=80=99s layout must also have been created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT flag set

  • If the descriptor pool from which srcSet was allocated was cre= ated with the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT f= lag set, then the descriptor pool from which dstSet was allocated must also have been created with the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT flag set

  • If the descriptor pool from which srcSet was allocated was cre= ated without the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT flag set, then the descriptor pool from which dstSet was alloc= ated must also have been created without the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT flag set

Valid Usage (Implicit)
  • sType <= strong class=3D"purple">must be VK_STRUCTURE_TYPE_COPY_DESCR= IPTOR_SET

  • pNext <= strong class=3D"purple">must be NULL

  • srcSet must be a valid VkDescriptorSe= t handle

  • dstSet must be a valid VkDescriptorSe= t handle

  • Both of dstSe= t, and srcSet must ha= ve been created, allocated, or retrieved from the same VkDevice

13.2.5. Descriptor Update T= emplates

A descriptor update template specifies a mapping from descriptor update information in host memory to descriptors in a descriptor set. It is designed to avoid passing redundant information to the driver when frequently updating the same set of descriptors in descriptor sets.

Descriptor update template objects are represented by VkDescriptorUpdateTemplate handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDescriptorUpdateTemplate)

or the equivalent

typedef VkDescriptorUpdateTemplate VkDescriptorUpdateTemplateK=
HR;

13.2.6. Descriptor Set Up= dates with Templates

Updating a large VkDescriptorSet array can be an expensive operation since an application must specify one VkWriteDescriptorSet structure for each descriptor or descriptor array to update, each of which re-specifies the same state when updating the same descriptor in multiple descriptor sets. For cases when an application wishes to update the same set of descriptors in multiple descriptor sets allocated using the same VkDescriptorSetLayout, vkUp= dateDescriptorSetWithTemplate can be used as a replacement for vkUpdateDescriptorSets.

VkDescriptorUpdateTemplate allows implementations to conver= t a set of descriptor update operations on a single descriptor set to an internal format that, in conjunction with vkUpdat= eDescriptorSetWithTemplate or vkCmdPushDescriptorSetWithTemplat= eKHR , can be more efficient compared to calli= ng vkUpdateDescriptorSets or vkCmdPushDescriptorSetKHR . The descriptors themselves are not specified in the VkDescriptorUpdateTemplate, rather, offsets into an applicatio= n provided pointer to host memory are specified, which are combined with a pointer passed to vkUpdateDescriptorSetW= ithTemplate or vkCmdPushDescriptorSetWithTemplat= eKHR . This allows large batches of updates to be executed without having to convert application data structures into a strictly-defined Vulkan data structure.

To create a descriptor update template, call:

VkResult vkCreateD=
escriptorUpdateTemplate(
    VkDevice                                    device,
    const VkDescriptorUpdateTemplateCreate=
Info* pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDescriptorUpdateTemplate*                 pDescriptorUpdateTemplate);=

or the equivalent command

VkResult vkCreateD=
escriptorUpdateTemplateKHR(
    VkDevice                                    device,
    const VkDescriptorUpdateTemplateCreate=
Info* pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDescriptorUpdateTemplate*                 pDescriptorUpdateTemplate);=
Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDescriptorUpdateTemplateCrea= teInfo structure is defined as:

typedef struct VkDescriptorUpda=
teTemplateCreateInfo {
    VkStructureType                           sType;
    void*                                 =
    pNext;
    VkDescriptorUpdateTemplateCreateFlags     flags;
    uint32_t                                  descriptorUpdateEntryCount;
    const VkDescriptorUpdateTemplateEntry*=
    pDescriptorUpdateEntries;
    VkDescriptorUpdateTemplateType            templateType;
    VkDescriptorSetLayout                     descriptorSetLayout;
    VkPipelineBindPoint                       pipelineBindPoint;
    VkPipelineLayout                          pipelineLayout;
    uint32_t                                  set;
} VkDescriptorUpdateTemplateCreateInfo;

or the equivalent

typedef VkDescriptorUpdateTemplateCreateInfo VkDescriptorUpdat=
eTemplateCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • descriptorUpdateEntryCount is the number of elements in the pDescriptorUpdateEntries array.

  • pDescriptorUpdateEntries is a pointer to an array of VkDescriptorUpdateTemplateEntry struct= ures describing the descriptors to be updated by the descriptor update template.

  • templateType Specifies the type of the descriptor update te= mplate. If set to VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET it can only be used to update descriptor set= s with a fixed descriptorSetLayout. If set to VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR it can only be used to push descriptor se= ts using the provided pipelineBindPoint, pipelineLayout, and set<= /code> number.

  • descriptorSetLayout is the descriptor set layout the parame= ter update template will be used with. All descriptor sets which are going to be updated through the newly created descriptor update template must b= e created with this layout. descriptorSetLayout is the descriptor set layout used to build= the descriptor update template. All descriptor sets which are going to be updated through the newly created descriptor update template must b= e created with a layout that matches (is the same as, or defined identically to) this layout. This parameter is ignored if templateType is not VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET.

  • pipelineBindPoint is a VkPipelineBindP= oint indicating whether the descriptors will be used by graphics pipelines or compute pipelines. This parameter is ignored if templateType is not VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR

  • pipelineLayout is a VkPipelineLayout = object used to program the bindings. This parameter is ignored if templateType is not VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR

  • set is the set number of the descriptor set in the pipeline= layout that will be updated. This parameter is ignored if templateType is not VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR

Valid Usage (Implicit)
  • sType must be VK_STRUCTUR= E_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO

  • pNext must be NULL=

  • flags must be 0

  • pDescriptorUpdateEntries must be a valid pointer to an array of descriptorUpd= ateEntryCount valid VkDescriptorUpdateTemplateEntry str= uctures

  • templateType must be= a valid VkDescriptorUpdateTemplateType= value

  • If descriptorSetLayout is not V= K_NULL_HANDLE, descriptorSetLayout must be a valid VkDescriptorSetLayout handle

  • descriptorUpdateEntryCount must be greater than 0

  • Bo= th of descriptorSetLayout, and pipelineLayout tha= t are valid handles must have been create= d, allocated, or retrieved from the same VkDevice

typedef VkFlags VkDescriptorUpdateTemplateCreateFlags;<=
/pre>

or the equivalent

typedef VkDescriptorUpdateTemplateCreateFlags VkDescriptorUpda=
teTemplateCreateFlagsKHR;

VkDescriptorUpdateTemplateCreateFlags is a bitmask type for= setting a mask, but is currently reserved for future use.

The VkDescriptorUpdateTemplateEntry structure is defined as= :

typedef struct VkDescriptorUpda=
teTemplateEntry {
    uint32_t            dstBinding;
    uint32_t            dstArrayElement;
    uint32_t            descriptorCount;
    VkDescriptorType    descriptorType;
    size_t              offset;
    size_t              stride;
} VkDescriptorUpdateTemplateEntry;

or the equivalent

typedef VkDescriptorUpdateTemplateEntry VkDescriptorUpdateTemp=
lateEntryKHR;
Valid Usage (Implicit)

To destroy a descriptor update template, call:

void vkDestroyDescriptorUpdateTemplate(
    VkDevice                                    device,
    VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
    const VkAllocationCallbacks*          =
      pAllocator);

or the equivalent command

void vkDestroyDescriptorUpdateTemplateKHR(
    VkDevice                                    device,
    VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that has been used to create t= he descriptor update template

  • descriptorUpdateTemplate is the descriptor update template = to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • If VkAllocationCallbacks were provided when descriptorSetLayout was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when descriptorSetLayout was created, pAllocator must be NULL

Valid Usage (Implicit)
Host Synchronization
  • Host access to descriptorUpdateTemplate must be externally synchronized

Once a VkDescriptorUpdateTemplate has been created, descrip= tor sets can be updated by calling:

void vkUpdateDescriptorSetWithTemplate(
    VkDevice                                    device,
    VkDescriptorSet                             descriptorSet,
    VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
    const void*                                 pData);

or the equivalent command

void vkUpdateDescriptorSetWithTemplateKHR(
    VkDevice                                    device,
    VkDescriptorSet                             descriptorSet,
    VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
    const void*                                 pData);
  • device is the logical device that updates the descriptor se= ts.

  • descriptorSet is the descriptor set to update

  • descriptorUpdateTemplate is the VkDescriptorUpdateTemplate which specifies the update mapping between pData and the descriptor set to update.

  • pData is a pointer to memory which contains one or more str= uctures of VkDescriptorImageInfo, VkBufferView used to write the descriptors.

Valid Usage
Valid Usage (Implicit)
  • <= code>device must be a valid = VkDevice handle

  • descriptorSet must be = a valid VkDescriptorSet handle

  • descriptorUpdateTemplate must be a valid VkDescriptorUpdateTemplate handl= e

  • descriptorUpdateTemplate must have been created, allocated, or retrieved from devic= e

Host Synchronization
  • Host access to descriptorSet must<= /strong> be externally synchronized

API example
struct AppBufferView {
    VkBufferView bufferView;
    uint32_t     applicationRelatedInformation;
};

struct AppDataStructure
{
    VkDescriptorImageInfo  imageInfo;          // a=
 single image info
    VkDescriptorBufferInfo bufferInfoArray[3=
]; // 3 buffer infos in an array
    AppBufferView          bufferView[2];   =
   // An application defined structure containing a=
 bufferView
    // ... some more application related data
};

const VkDescriptorUpdateTemplateEntry desc=
riptorUpdateTemplateEntries[] =3D
{
    // binding to a single image descriptor
    {
        0,                                  =
         // binding
        0,                                  =
         // dstArrayElement
        1,                                  =
         // descriptorCount
        VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,   // descriptorType
        offsetof(AppDataStructure, imageInfo),       // offset
        0                                   =
         // stride is not required if descriptorCou=
nt is 1.
    },

    // binding to an array of buffer descriptors
    {
        0,                                  =
         // binding
        0,                                  =
         // dstArrayElement
        3,                                  =
         // descriptorCount
        VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,           // descriptorType
        offsetof(AppDataStructure, bufferInfoArray), // offset
        sizeof(VkDescriptorBufferInfo)      =
         // stride, descriptor buffer infos are com=
pact
    },

    // binding to an array of buffer views
    {
        0,                                  =
         // binding
        3,                                  =
         // dstArrayElement
        1,                                  =
         // descriptorCount
        VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,     // descriptorType
        offsetof(AppDataStructure, bufferView),      // offset
        sizeof(AppBufferView)               =
         // stride, bufferViews do not have to be c=
ompact
    },
};

// create an descriptor update template for descrip=
tor set updates
const VkDescriptorUpdateTemplateCreateInfo=
 createInfo =3D
{
    VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,  // sType
    NULL,                       =
                                   // pNext
    0,                                      =
                       // flags
    3,                                      =
                       // descriptorUpdateEntryCoun=
t
    descriptorUpdateTemplateEntries,                               // pDescriptorUpdateEntries
    VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,         // templateType
    myLayout,                                                      // descriptorSetLayout
    0,                                      =
                       // pipelineBindPoint, ignore=
d by given templateType
    0,                                      =
                       // pipelineLayout, ignored b=
y given templateType
    0,                                      =
                       // set, ignored by given tem=
plateType
};

VkDescriptorUpdateTemplate myDescriptorUpdateTemplate;
myResult =3D vkCreateDescriptorUpdateTemplate(
    myDevice,
    &createInfo,
    NULL,
    &myDescriptorUpdateTemplate);
}


AppDataStructure appData;

// fill appData here or cache it in your engine
vkUpdateDescriptorSetWithTemplate(myDevice, myDescriptorSet, myDescriptorUp=
dateTemplate, &appData);

13.2.7. Descriptor Set Binding

To bind one or more descriptor sets to a command buffer, call:

void vkCmdBindDescriptorSets(
    VkCommandBuffer                             commandBuffer,
    VkPipelineBindPoint                         pipelineBindPoint,
    VkPipelineLayout                            layout,
    uint32_t                                    firstSet,
    uint32_t                                    descriptorSetCount,
    const VkDescriptorSet*                =
      pDescriptorSets,
    uint32_t                                    dynamicOffsetCount,
    const uint32_t*                       =
      pDynamicOffsets);
  • commandBuffer is the command buffer that the descriptor set= s will be bound to.

  • pipelineBindPoint is a VkPipelineBindP= oint indicating whether the descriptors will be used by graphics pipelines or compute pipelines. There is a separate set of bind points for each of graphics and compute, so binding one does not disturb the other.

  • layout is a VkPipelineLayout object u= sed to program the bindings.

  • firstSet is the set number of the first descriptor set to b= e bound.

  • descriptorSetCount is the number of elements in the pDescriptorSets array.

  • pDescriptorSets is an array of handles to = VkDescriptorSet objects describing the descriptor sets to write to.

  • dynamicOffsetCount is the number of dynamic offsets in the pDynamicOffsets array.

  • pDynamicOffsets is a pointer to an array of uint32_t<= /code> values specifying dynamic offsets.

vkCmdBindDescriptorSets causes the sets numbered [fir= stSet.. firstSet+descriptorSetCount-1] to use the binding= s stored in pDescriptorSets[0..descriptorSetCount-1] for subs= equent rendering commands (either compute or graphics, according to the pipelineBindPoint). Any bindings that were previously applied via these sets are no longer valid.

Once bound, a descriptor set affects rendering of subsequent graphics or compute commands in the command buffer until a different set is bound to th= e same set number, or else until the set is disturbed as described in Pipeline Layout Compatibility.

A compatible descriptor set must be bo= und for all set numbers that any shaders in a pipeline access, at the time that a draw or dispatch command i= s recorded to execute using that pipeline. However, if none of the shaders in a pipeline statically use any bindings with a particular set number, then no descriptor set need be bound for that set number, even if the pipeline layout includes a non-trivial descriptor set layout for that set number.

If any of the sets being bound include dynamic uniform or storage buffer= s, then pDynamicOffsets includes one element for each array eleme= nt in each dynamic descriptor type binding in each set. Values are taken from pDynamicOffsets in an order such that al= l entries for set N come before set N+1; within a set, entries are ordered by the binding numbers in the descriptor set layouts; and within a binding array, elements are in order. dynamicOffsetCount must equa= l the total number of dynamic descriptors in the sets being bound.

The effective offset used for dynamic uniform and storage buffer binding= s is the sum of the relative offset taken from pDynamicOffsets, and= the base address of the buffer plus base offset in the descriptor set. The range of the dynamic uniform and storage buffer bindings is the buffer range as specified in the descriptor set.

Each of the pDescriptorSets must be compatible with the pipeline layout specified by layout. The layout used to program the bindings must also be compatible with the pipeline used in subsequent graphics or compute commands, as defined in the Pipeline Layout Compatibility section.

The descriptor set contents bound by a call to vkCmdBindDescriptor= Sets may be consumed at the following times:

  • For descriptor bindings created with the VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT bit set, the contents may be consumed when the command= buffer is submitted to a queue, or during shader execution of the resulting draws and dispatches, or any time in between. Otherwise,

  • during host execution of the command, or during shader execution of the resulting draws and dispatches, or any time in between.

Thus, the contents of a descriptor set binding = must not be altered (overwritten by an update command, or freed) between the first point in tim= e that it may be consumed, and when the com= mand completes executing on the queue.

The contents of pDynamicOffsets are consumed immediately du= ring execution of vkCmdBindDescriptorSets. Once all pending uses have completed, it is legal to update and reuse a descriptor set.

Valid Usage
  • Each element of pDescriptorSets must<= /strong> have been allocated with a VkDescriptorSetLayout that matches (is the same as, or identic= ally defined as) the VkDescriptorSetLayout at set n in layout, where n is the sum of firstSet and the index into pDescriptorSets

  • dynamicOffsetCount must be e= qual to the total number of dynamic descriptors in pDescriptorSets

  • The sum of firstSet and descriptorSetCount must be less than or equal to VkPipelineLayoutCreateInfo::setLayoutCo= unt provided when layout was created

  • pipelineBindPoint must be su= pported by the commandBuffer=E2=80=99s parent VkCommandPool=E2=80=99s queue family

  • Each element of pDynamicOffsets which corresponds to a descrip= tor binding with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment<= /code>

  • Each element of pDynamicOffsets which corresponds to a descrip= tor binding with type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC must be a multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment<= /code>

  • For each dynamic uniform or storage buffer binding in pDescriptorSets, the sum of the effective offset, as defined above, and the range of the binding must = be less than or equal to the size of the buffer

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • = pipelineBindPoint must be a = valid VkPipelineBindPoint value

  • layou= t must be a valid VkPipeline= Layout handle

  • pDescriptorSets must be a vali= d pointer to an array of descriptorSetCount valid VkDesc= riptorSet handles

  • If= dynamicOffsetCount is not 0, pDynamicOffse= ts must be a valid pointer to an a= rray of dynamicOffsetCount uint32_t values

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from= must support graphics, or compute operat= ions

  • descriptorSetCount must b= e greater than 0

  • Each of c= ommandBuffer, layout, and the elements of pDescri= ptorSets must have been created, a= llocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

13.2.8. Push Descriptor Updates<= /h4>

In addition to allocating descriptor sets and binding them to a command buffer, an application can record descrip= tor updates into the command buffer.

To push descriptor updates into a command buffer, call:

void vkCmdPushDescriptorSetKHR(
    VkCommandBuffer                             commandBuffer,
    VkPipelineBindPoint                         pipelineBindPoint,
    VkPipelineLayout                            layout,
    uint32_t                                    set,
    uint32_t                                    descriptorWriteCount,
    const VkWriteDescriptorSet*           =
      pDescriptorWrites);
  • commandBuffer is the command buffer that the descriptors wi= ll be recorded in.

  • pipelineBindPoint is a VkPipelineBindP= oint indicating whether the descriptors will be used by graphics pipelines or compute pipelines. There is a separate set of push descriptor bindings for each of graphics and compute, so binding one does not disturb the other.

  • layout is a VkPipelineLayout object u= sed to program the bindings.

  • set is the set number of the descriptor set in the pipeline= layout that will be updated.

  • descriptorWriteCount is the number of elements in the pDescriptorWrites array.

  • pDescriptorWrites is a pointer to an array of VkWriteDescriptorSet structures describing the de= scriptors to be updated.

Push descriptors are a small bank of descriptors whose storage = is internally managed by the command buffer rather than being written into a descriptor set and later bound to a command buffer. Push descriptors allow for incremental updates of descriptors without managing the lifetime of descriptor sets.

When a command buffer begins recording, all push descriptors have undefi= ned contents. Push descriptors can be updated increment= ally and cause shaders to use the updated descriptors for subsequent rendering commands (either compute or graphics, according to the pipelineBindPoint) until the descri= ptor is overwritten, or else until the set is disturbed as described in Pipeline Layout Compatibility. When the set is disturbed or push descriptors with a different descriptor set layout are set, all push descriptors become invalid.

Valid descriptors must be pushed for a= ll bindings that any shaders in a pipeline access, at the time that a draw or dispatch command is recorded to execute using that pipeline. This includes immutable sampler descriptors, which must be pushed before they are accessed by a pipeline. However, if none of the shaders in a pipeline statically use certain bindings in the push descriptor set, then those descriptors need not be valid.

Push descriptors do not use dynamic offsets. Instead, the corresponding non-dynamic descriptor types can be used and the offset member of VkDescriptorBufferInf= o can be changed each time the descriptor is written.

Each element of pDescriptorWrites is interpreted as in VkWriteDescriptorSet, except the dstSet member is ignored.

To push an immutable sampler, use a VkWriteDescrip= torSet with dstBinding and dstArrayElement selecting the immu= table sampler=E2=80=99s binding. If the descriptor type is VK_DESCRIPTOR_TYPE_SAMPLER, the pImageInfo parameter is ignored and the immutable sampler is t= aken from the push descriptor set layout in the pipeline layout. If the descriptor type is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, the sampler member of the pImageInfo parameter is= ignored and the immutable sampler is taken from the push descriptor set layout in the pipeline layout.

Valid Usage
  • pipelineBindPoint must be su= pported by the commandBuffer=E2=80=99s parent VkCommandPool=E2=80=99s queue family

  • set must be less than VkPipelineLayoutCreateInfo::setLayoutCount provid= ed when layout was created

  • set must be the unique set n= umber in the pipeline layout that uses a descriptor set layout that was created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR

Valid Usage (Implicit)
Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

13.2.9= . Push Descriptor Updates with Descriptor Update Templates

It is also possible to use a descriptor update template to specify the p= ush descriptors to update. To do so, call:

void vkCmdPushDescriptorSetWithTemplateKHR(
    VkCommandBuffer                             commandBuffer,
    VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
    VkPipelineLayout                            layout,
    uint32_t                                    set,
    const void*                                 pData);
  • commandBuffer is the command buffer that the descriptors wi= ll be recorded in.

  • descriptorUpdateTemplate A descriptor update template which defines how to interpret the descriptor information in pData.

  • layout is a VkPipelineLayout object u= sed to program the bindings. It must be compatible with the layout use= d to create the descriptorUpdateTemplate handle.

  • set is the set number of the descriptor set in the pipeline= layout that will be updated. This must be the same number used to crea= te the descriptorUpdateTemplate handle.

  • pData Points to memory which contains the descriptors for t= he templated update.

Valid Usage
Valid Usage (Implicit)
  • commandBuffer must= be a valid VkCommandBuffer handle

  • descriptorUpdateTemplate must be a valid VkDescriptorUpdateTemplate h= andle

  • layout must be a valid VkPipelineLayout handle

  • commandBuffer must= be in the recording state

  • The VkCommandPool that commandBuffer was = allocated from must support graphics, or = compute operations

  • E= ach of commandBuffer, descriptorUpdateTemplate, a= nd layout must have been cre= ated, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

API example
struct AppBufferView {
    VkBufferView bufferView;
    uint32_t     applicationRelatedInformation;
};

struct AppDataStructure
{
    VkDescriptorImageInfo  imageInfo;          // a=
 single image info
    // ... some more application related data
};

const VkDescriptorUpdateTemplateEntry desc=
riptorUpdateTemplateEntries[] =3D
{
    // binding to a single image descriptor
    {
        0,                                  =
         // binding
        0,                                  =
         // dstArrayElement
        1,                                  =
         // descriptorCount
        VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,   // descriptorType
        offsetof(AppDataStructure, imageInfo),       // offset
        0                                   =
         // stride is not required if descriptorCou=
nt is 1.
    }

};

// create an descriptor update template for descrip=
tor set updates
const VkDescriptorUpdateTemplateCreateInfo=
 createInfo =3D
{
    VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,  // sType
    NULL,                       =
                                   // pNext
    0,                                      =
                       // flags
    1,                                      =
                       // descriptorUpdateEntryCoun=
t
    descriptorUpdateTemplateEntries,                               // pDescriptorUpdateEntries
    VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR,       // templateType
    0,                                      =
                       // descriptorSetLayout, igno=
red by given templateType
    VK_PIPELINE_BIND_POINT_GRAPHICS,                               // pipelineBindPoint
    myPipelineLayout,                                              // pipelineLayout
    0,                                      =
                       // set
};

VkDescriptorUpdateTemplate myDescriptorUpdateTemplate;
myResult =3D vkCreateDescriptorUpdateTemplate(
    myDevice,
    &createInfo,
    NULL,
    &myDescriptorUpdateTemplate);
}

AppDataStructure appData;
// fill appData here or cache it in your engine
vkCmdPushDescriptorSetWithTemplateKHR(myCmdBuffer, myDescriptorUpdateTempla=
te, myPipelineLayout, 0,&appData);

13.2.10. Push Constant Updates

As described above in section Pipeline Layouts, the pipeline layout defines shader push constants which are updated via Vulkan commands rather than via writes to memory or copy commands.

Note

Push constants represent a high speed path to modify constant data in pipelines that is expected to outperform memory-backed resource updates.

The values of push constants are undefined at the start of a command buf= fer.

To update push constants, call:

void vkCmdPushConstants(
    VkCommandBuffer                             commandBuffer,
    VkPipelineLayout                            layout,
    VkShaderStageFlags                          stageFlags,
    uint32_t                                    offset,
    uint32_t                                    size,
    const void*                                 pValues);
  • commandBuffer is the command buffer in which the push const= ant update will be recorded.

  • layout is the pipeline layout used to program the push cons= tant updates.

  • stageFlags is a bitmask of VkShaderS= tageFlagBits specifying the shader stages that will use the push constants in the updated range.

  • offset is the start offset of the push constant range to up= date, in units of bytes.

  • size is the size of the push constant range to update, in u= nits of bytes.

  • pValues is an array of size bytes containing t= he new push constant values.

Valid Usage
  • For each byte in the range specified by offset and size<= /code> and for each shader stage in stageFlags, there must be a push constant range in layout that includes that byte and that stag= e

  • For each byte in the range specified by offset and size<= /code> and for each push constant range that overlaps that byte, stageFlags must include all stages in that push cons= tant range=E2=80=99s VkPushConstantRange::stageFlags

  • offset must be a multiple of= 4

  • size must be a multiple of <= code>4

  • offset must be less than VkPhysicalDeviceLimits::maxPushConstantsSize

  • size must be less than or eq= ual to VkPhysicalDeviceLimits::maxPushConstantsSize minu= s offset

Valid Usage (Implicit)
  • com= mandBuffer must be a valid V= kCommandBuffer handle

  • layout must be a valid VkPipelineLayou= t handle

  • stageF= lags must be a valid combination o= f VkShaderStageFlagBits values

  • = stageFlags must not be 0

  • pValues must be a valid pointer to an array= of size bytes

  • com= mandBuffer must be in the recording state

  • The V= kCommandPool that commandBuffer was allocated from must support graphics, or compute operations<= /p>

  • size must be greater than 0

  • Both of comman= dBuffer, and layout must have been created, allocated, or retrieved from the same VkDevice=

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

14. Shader Interfaces

When a pipeline is created, the set of shaders specified in the corresponding Vk*PipelineCreateInfo structure are implicitly l= inked at a number of different interfaces.

Interface definitions make use of the following SPIR-V decorations:

  • DescriptorSet and Binding

  • Location, Component, and Index

  • Flat, NoPerspective, Centroid, an= d Sample

  • Block and BufferBlock

  • InputAttachmentIndex

  • Offset, ArrayStride, and MatrixStride

  • BuiltIn

  • PassthroughNV

This specification describes valid uses for Vulkan of these decorations. Any other use of one of these decorations is invalid.

14.1. Shader Input and Output Interfaces=

When multiple stages are present in a pipeline, the outputs of one stage form an interface with the inputs of the next stage. When such an interface involves a shader, shader outputs are matched agains= t the inputs of the next stage, and shader inputs are matched against the outputs of the previous stage.

There are two classes of variables that can be matched between shader stages, built-in variables and user-defined variables. Each class has a different set of matching criteria. Generally, when non-shader stages are between shader stages, the user-defined variables, and most built-in variables, form an interface between the shader stages.

The variables forming the input or output interfaces are listed= as operands to the OpEntryPoint instruction and are declared with= the Input or Output storage classes, respectively, in= the SPIR-V module.

Output variables of a shader stage have undefined values un= til the shader writes to them or uses the Initializer operand when dec= laring the variable.

14.1.1. Built-in Interface Block=

Shader built-in variables meeting the following requirements define the built-in interface block. They must

  • be explicitly declared (there are no implicit built-ins),

  • be identified with a BuiltIn decoration,

  • form object types as described in the Built-in Variables section, and

  • be declared in a block whose top-level members are the built-ins.

Built-ins only participate in interface matching if they are declared in such a block. They must not have any Location or Component decorations.

There must be no more than one built-i= n interface block per shader per interface.

14.1.2. User-defined Variable Inter= face

The remaining variables listed by OpEntryPoint with the Input or Output storage class form the user-defined variable interf= ace. By default such variables have a type with a width of 32 or 64. If an implementation supports storageInputOutput16, user-defined variables in the Input and Output st= orage classes can also have types with a width of 16. These variables must be identified with a= Location decoration and can also be identified with a Component decoration.

14.1.3. Interface Matching

A user-defined output variable is considered to match an input variable = in the subsequent stage if the two variables are declared with the same Location and Component decoration and match in ty= pe and decoration, except that interpolation decorations are not required to match= . For the purposes of interface matching, variables declared without a Component decoration are considered to have a Component<= /code> decoration of zero.

Note

Matching rules for passthrough geometry shaders are slightly di= fferent and are described in the Passthrough Interface Matching section.

Variables or block members declared as structures are considered to matc= h in type if and only if the structure members match in type, decoration, number= , and declaration order. Variables or block members declared as arrays are considered to match in type only if both declarations specify the same element type and size.

Tessellation control shader per-vertex output variables and blocks, and tessellation control, tessellation evaluation, and geometry shader per-vertex input variables and blocks are required to be declared as arrays= , with each element representing input or output values for a single vertex o= f a multi-vertex primitive. For the purposes of interface matching, the outermost array dimension of such variables and blocks is ignored.

At an interface between two non-fragment shader stages, the built-in interface block must match exactly, as de= scribed above. At an interface involving the fragment shader inputs, the presence or absence of any built-in output does not affect the interface matching.

At an interface between two shader stages, the user-defined variable interface must match exactly, as describe= d above.

Any input value to a shader stage is well-defined as long as the precedi= ng stages writes to a matching output, as described above.

Additionally, scalar and vector inputs are well-defined if there is a corresponding output satisfying all of the following conditions:

  • the input and output match exactly in decoration,

  • the output is a vector with the same basic type and has at least as many components as the input, and

  • the common component type of the input and output is 16-bit integer or floating-point, or 32-bit integer or floating-point (64-bit component types are excluded).

In this case, the components of the input will be taken from the first components of the output, and any extra components of the output will be ignored.

14.1.4. Location Assignment

This section describes how many locations are consumed by a given type. As mentioned above, geometry shader inputs, tessellation control shader inputs and outputs, and tessellation evaluation inputs all have an additional level of arrayness relative to other shader inputs and outputs. This outer array level is removed from the type before considering how many locations the type consumes.

The Location value specifies an interface slot comprised of= a 32-bit four-component vector conveyed between stages. The Component specifies components within these vector locations. Only types with widths of 16, 32 or 64 are supported in shader interfaces.

Inputs and outputs of the following types consume a single interface location:

  • 16-bit scalar and vector types, and

  • 32-bit scalar and vector types, and

  • 64-bit scalar and 2-component vector types.

64-bit three- and four-component vectors consume two consecutive locatio= ns.

If a declared input or output is an array of size n and each el= ement takes m locations, it will be assigned m =C3=97 n cons= ecutive locations starting with the location specified.

If the declared input or output is an n =C3=97 m 16-, 32- or 64-bit matrix, it will be assigned multiple locations starting with the location specified. The number of locations assigned for each matrix will be the same as for an n-element array of m-component vectors.

The layout of a structure type used as an Input or Ou= tput depends on whether it is also a Block (i.e. has a Block d= ecoration).

If it is a not a Block, then the structure type must have a Location decoration. Its members are assigned consecutive locations in their declaration order, with the first member assigned to the location specified for the structure type. The members, and their nested types, must= not themselves have Location decorations.

If the structure type is a Block but without a Locati= on, then each of its members must have a Location= decoration. If it is a Block with a Location decoration, then= its members are assigned consecutive locations in declaration order, starting from the firs= t member which is initially assigned the location specified for the Block. Any member with its own Location decoration is assigned that l= ocation. Each remaining member is assigned the location after the immediately preceding member in declaration order.

The locations consumed by block and structure members are determined by applying the rules above in a depth-first traversal of the instantiated members as though the structure or block member were declared as an input o= r output variable of the same type.

Any two inputs listed as operands on the same OpEntryPoint = must not be assigned the same location, either explicitly or implicitly. Any two outputs listed as operands on the same OpEntryPoint must not be assigned the same location, either explicitly or implicitly.

The number of input and output locations available for a shader input or output interface are limited, and dependent on the shader stage as describe= d in Shader Input and Output Locations.

Table 18. Shader Input and Output Locations
Shader Interface Locations Available

ver= tex input

maxVertexInputAttributes

ver= tex output

maxVertexOutputComponents / 4

tes= sellation control input

maxTessellationControlPerVertexInputComponents / 4

tes= sellation control output

maxTessellationControlPerVertexOutputComponents / 4

tes= sellation evaluation input

maxTessellationEvaluationInputComponents / 4

tes= sellation evaluation output

maxTessellationEvaluationOutputComponents / 4

geo= metry input

maxGeometryInputComponents / 4

geo= metry output

maxGeometryOutputComponents / 4

fra= gment input

maxFragmentInputComponents / 4

fra= gment output

maxFragmentOutputAttachments

14.1.5. Component Assignment<= /h4>

The Component decoration allows the Location t= o be more finely specified for scalars and vectors, down to the individual components within a location that are consumed. The components within a location are 0, 1, 2, and 3. A variable or block member starting at component N will consume components N, N+1, N+2, =E2=80=A6=E2=80=8B up through its size. For 16-, and 32-bit types, it is invalid if this sequence of components gets larger than 3. A scalar 64-bit type will consume two of these components in sequence, and = a two-component 64-bit vector type will consume all four components available within a location. A three- or four-component 64-bit vector type must= not specify a Component decoration. A three-component 64-bit vector type will consume all four components of th= e first location and components 0 and 1 of the second location. This leaves components 2 and 3 available for other component-qualified declarations.

A scalar or two-component 64-bit data type must= not specify a Component decoration of 1 or 3. A Component decoration must = not be specified for any type that is not a scalar or vector.

14.2. Vertex Input Interface

When the vertex stage is present in a pipeline, the vertex shader input variables form an interface with the vertex input attributes. The vertex shader input variables are matched by the Location = and Component decorations to the vertex input attributes specified= in the pVertexInputState member of the = VkGraphicsPipelineCreateInfo structure.

The vertex shader input variables listed by OpEntryPoint wi= th the Input storage class form the vertex input interface. These variables must be identified with a= Location decoration and can also be identified with a Component decoration.

For the purposes of interface matching: variables declared without a Component decoration are considered to have a Component<= /code> decoration of zero. The number of available vertex input locations is given by the maxVertexInputAttributes member of the VkPhysicalDeviceL= imits structure.

All vertex shader inputs declared as above must= have a corresponding attribute and binding in the pipeline.

14.3. Fragment Output Interface

When the fragment stage is present in a pipeline, the fragment shader outputs form an interface with the output attachments of the current subpass. The fragment shader output variables are matched by the Location and Component decorations to the color attachments specified in th= e pColorAttachments array of the VkSubpass= Description structure that describes the subpass that the fragment shader is executed in.

The fragment shader output variables listed by OpEntryPoint= with the Output storage class form the fragment output interface. These variables must be identified with a= Location decoration. They can also be identified with a = Component decoration and/or an Index decoration. For the purposes of interface matching: variables declared without a Component decoration are considered to have a Component<= /code> decoration of zero, and variables declared without an Index decoration ar= e considered to have an Index decoration of zero.

A fragment shader output variable identified with a Location decoration of i is directed to the color attachment indicated by pColorAttachments[i], after passing through the blend= ing unit as described in Blending, if enabled. Locations are consumed as described in Location Assignment. The number of available fragment output locations is given by the maxFragmentOutputAttachments member of the VkPhysicalDeviceLimits structure.

Components of the output variables are assigned as described in Component Assignment. Output components identified as 0, 1, 2, and 3 will be directed to the R, G= , B, and A inputs to the blending unit, respectively, or to the output attachment if blending is disabled. If two variables are placed within the same location, they must have the same underlying type (floating-point or integer). The input to blending or color attachment writes is undefined for component= s which do not correspond to a fragment shader output.

Fragment outputs identified with an Index of zero are direc= ted to the first input of the blending unit associated with the corresponding Location. Outputs identified with an Index of one are directed to the se= cond input of the corresponding blending unit.

No component aliasing of output variables is allowed, that is t= here must not be two output variables which have the same location, component, and index, either explicitly declared or implied.

Output values written by a fragment shader must= be declared with either OpTypeFloat or OpTypeInt, and a Width of 32. If storageInputOutput16 is supported, output values written by= a fragment shader can be also declared with= either OpTypeFloat or OpTypeInt and a Width of 16. Composites of these types are also permitted. If the color attachment has a signed or unsigned normalized fixed-point format, color values are assumed to be floating-point and are converted to fixed-point as described in Conversion from Float= ing-Point to Normalized Fixed-Point; If the color attachment has an integer format, color values are assumed to be integers and converted to the bit-depth of the target. Any value that cannot be represented in the attachment=E2=80=99s format is undefined. For any other attachment format no conversion is performed. If the type of the values written by the fragment shader do not match the format of the corresponding color attachment, the result is undefined for those components.

14.4. Fragment Input Attachment Inter= face

When a fragment stage is present in a pipeline, the fragment shader subp= ass inputs form an interface with the input attachments of the current subpass. The fragment shader subpass input variables are matched by InputAttachmentIndex decorations to the input attachments spec= ified in the pInputAttachments array of the VkSub= passDescription structure that describes the subpass that the fragment shader is executed in.

The fragment shader subpass input variables with the UniformConsta= nt storage class and a decoration of InputAttachmentIndex that ar= e statically used by OpEntryPoint form the fragment input at= tachment interface. These variables must be declared with a t= ype of OpTypeImage, a Dim operand of SubpassData, and a Sampled operand of 2.

A subpass input variable identified with an InputAttachmentIndex decoration of i reads from the input attachment indicated by pInputAttachments[i] member of VkSubpassDescrip= tion. If the subpass input variable is declared as an array of size N, it consume= s N consecutive input attachments, starting with the index specified. There must not be more than one input var= iable with the same InputAttachmentIndex whether explicitly declared or implied by= an array declaration. The number of available input attachment indices is given by the maxPerStageDescriptorInputAttachments member of the VkPhysicalDeviceLimits structure.

Variables identified with the InputAttachmentIndex must only be used by a fragment stage. The basic data type (floating-point, integer, unsigned integer) of the subpass input must match the basic format= of the corresponding input attachment, or the values of subpass loads from these variables are undefined.

See Input Attachment for more detail= s.

14.6. Built-In Variables

Built-in variables are accessed in shaders by declaring a variable decor= ated with a BuiltIn decoration. The meaning of each BuiltIn decoration is as follows. In the remainder of this section, the name of a built-in is used interchangeably with a term equivalent to a variable decorated with that particular built-in. Built-ins that represent integer values can be declared as either signed or unsigned 32-bit integers.

BaryCoordNoPerspAMD

The BaryCoordNoPerspAMD decoration can be used to decorate a fragment shader input variable. This variable will contain the (I,J) pair of the barycentric coordinates corresponding to the fragment evaluated using linear interpolation at the pixel=E2=80=99s center. The K coordinate of the barycentric coordinates ca= n be derived given the identity I + J + K =3D 1.0.

BaryCoordNoPerspCentroidAMD

The BaryCoordNoPerspCentroidAMD decoration can be used to decorate a fragment shader input variable. This variable will contain the (I,J) pair of the barycentric coordinates corresponding to the fragment evaluated using linear interpolation at the centroid. The K coordinate of the barycentric coordinates ca= n be derived given the identity I + J + K =3D 1.0.

BaryCoordNoPerspSampleAMD

The BaryCoordNoPerspCentroidAMD decoration can be used to decorate a fragment shader input variable. This variable will contain the (I,J) pair of the barycentric coordinates corresponding to the fragment evaluated using linear interpolation at each covered sample. The K coordinate of the barycentric coordinates ca= n be derived given the identity I + J + K =3D 1.0.

BaryCoordPullModelAMD

The BaryCoordPullModelAMD decoration can be used to decorate a fragment shader input variable. This variable will contain (1/W, 1/I, 1/J) evaluated at the pixel center an= d can be used to calculate gradients and th= en interpolate I, J, and W at any desired sample location.

BaryCoordSmoothAMD

The BaryCoordSmoothAMD decoration = can be used to decorate a fragment shader input variable. This variable will contain the (I,J) pair of the barycentric coordinates corresponding to the fragment evaluated using perspective interpolation at the pixel=E2=80=99s center. The K coordinate of the barycentric coordinates ca= n be derived given the identity I + J + K =3D 1.0.

BaryCoordSmoothCentroidAMD

The BaryCoordSmoothCentroidAMD decoration can be used to decorate a fragment shader input variable. This variable will contain the (I,J) pair of the barycentric coordinates corresponding to the fragment evaluated using perspective interpolation at the centroid. The K coordinate of the barycentric coordinates ca= n be derived given the identity I + J + K =3D 1.0.

BaryCoordSmoothSampleAMD

The BaryCoordSmoothCentroidAMD decoration can be used to decorate a fragment shader input variable. This variable will contain the (I,J) pair of the barycentric coordinates corresponding to the fragment evaluated using perspective interpolation at each covered sample. The K coordinate of the barycentric coordinates ca= n be derived given the identity I + J + K =3D 1.0.

BaseInstance

Decorating a variable with the BaseInstance built-in will m= ake that variable contain the integer value corresponding to the first instance that was passed to the command that invoked the current vertex shader invocation= . BaseInstance is the firstInstance parameter to a = direct drawing command or the firstInstance member of a structure consum= ed by an indirect drawing command.

The BaseInstance decoration must be used only within vertex shaders.

The variable decorated with BaseInstance must be declared using the input storage class.

The variable decorated with BaseInstance must be declared as a scalar 32-bit integer.

BaseVertex

Decorating a variable with the BaseVertex built-in will mak= e that variable contain the integer value corresponding to the first vertex or vertex offset that was passed to the command that invoked the current verte= x shader invocation. For non-indexed drawing commands, this variable is the first= Vertex parameter to a direct drawing command or the firstVertex member of the structure consumed by an indirect drawing command. For indexed drawing commands, this variable is the vertexOff= set parameter to a direct drawing command or the vertexOffset member of the structure consumed by an indirect drawing command.

The BaseVertex decoration must be used only within vertex shaders.

The variable decorated with BaseVertex must be declared using the input storage class.

The variable decorated with codeBaseVertex must= be declared as a scalar 32-bit integer.

ClipDistance

Decorating a variable with the ClipDistance built-in decora= tion will make that variable contain the mechanism for controlling user clipping. ClipDistance is an array such that the ith element = of the array specifies the clip distance for plane i. A clip distance of 0 means the vertex is on the plane, a positive distance means the vertex is inside the clip half-space, and a negative distance means the point is outside the clip half-space.

The ClipDistance decoration must be used only within vertex, fragment, tessellation control, tessellation evaluation, and geometry shaders.

In vertex shaders, any variable decorated with ClipDistance= must be declared using the Output storage class.

In fragment shaders, any variable decorated with ClipDistance must be declared using the Input storage class.

In tessellation control, tessellation evaluation, or geometry shaders, a= ny variable decorated with ClipDistance = must not be in a storage class other than Input or Output.

Any variable decorated with ClipDistance must be declared as an array of 32-bit floating-point values.

Note

The array variable decorated with ClipDistance is explicitl= y sized by the shader.

Note

In the last vertex processing stage, these values will be linearly interpolated across the primitive and the portion of the primitive with interpolated distances less than 0 will be considered outside the clip volume. If ClipDistance is then used by a fragment shader, ClipD= istance contains these linearly interpolated values.

CullDistance

Decorating a variable with the CullDistance built-in decora= tion will make that variable contain the mechanism for controlling user culling. If any member of this array is assigned a negative value for all vertices belonging to a primitive, then the primitive is discarded before rasterization.

The CullDistance decoration must be used only within vertex, fragment, tessellation control, tessellation evaluation, and geometry shaders.

In vertex shaders, any variable decorated with CullDistance= must be declared using the Output storage class.

In fragment shaders, any variable decorated with CullDistance must be declared using the Input storage class.

In tessellation control, tessellation evaluation, or geometry shaders, a= ny variable decorated with CullDistance = must not be declared in a storage class other than input or output.

Any variable decorated with CullDistance must be declared as an array of 32-bit floating-point values.

Note

In fragment shaders, the values of the CullDistance array a= re linearly interpolated across each primitive.

Note

If CullDistance decorates an input variable, that variable = will contain the corresponding value from the CullDistance decorated output= variable from the previous shader stage.

DeviceIndex

The DeviceIndex decoration can be applied to a shader input which will be filled with the device index of the physical device that is executing th= e current shader invocation. This value will be in the range \([0,max(1,physicalDeviceCount))\), where physicalDeviceCount is the physicalDeviceCount member of VkDeviceGroupDeviceCreateInfo.

The DeviceIndex decoration can be used in any shader.

The variable decorated with DeviceIndex must be declared using the Input storage class.

The variable decorated with DeviceIndex must be declared as a scalar 32-bit integer.

DrawIndex

Decorating a variable with the DrawIndex built-in will make= that variable contain the integer value corresponding to the zero-based index of the drawing command that invoked the current vertex shader invocation. For indirect drawing commands, DrawIndex begins at ze= ro and increments by one for each draw command executed. The number of draw commands is given by the drawCount paramete= r. For direct drawing commands, DrawIndex is always zero= . DrawIndex is dynamically uniform.

The DrawIndex decoration must be used only within vertex shaders.

The variable decorated with DrawIndex must be declared using the input storage class.

The variable decorated with DrawIndex must be declared as a scalar 32-bit integer.

FragCoord

Decorating a variable with the FragCoord built-in decoratio= n will make that variable contain the framebuffer coordinate \((x,y,z,\frac{1}{w})\) of the fragment being processed. The (x,y) coordinate (0,0) is the upper left corner of the upper left pixel in the framebuffer.

When Sample Shading is enabled, the x and y components of FragCoord reflect th= e location of one of the samples corresponding to the shader invocation.

When sample shading is not enabled, the x and = y components of FragCoord reflect the location of the center of the pixel, (0.5,0.5).

The z component of FragCoord is t= he interpolated depth value of the primitive.

The w component is the interpolated \(\frac{1}= {w}\).

The FragCoord decoration must be used only within fragment shaders.

The variable decorated with FragCoord must be declared using the Input storage class.

The Centroid interpolation decoration is ignored, but allow= ed, on FragCoord.

The variable decorated with FragCoord must be declared as a four-component vector of 32-bit floating-point values.

FragDepth

Decorating a variable with the FragDepth built-in decoratio= n will make that variable contain the new depth value for all samples covered by the fragment. This value will be used for depth testing and, if the depth test passes, an= y subsequent write to the depth/stencil attachment.

To write to FragDepth, a shader mu= st declare the DepthReplacing execution mode. If a shader declares the DepthReplacing execution mode and the= re is an execution path through the shader that does not set FragDepth,= then the fragment=E2=80=99s depth value is undefined for executions of the shader th= at take that path.

The FragDepth decoration must be used only within fragment shaders.

The variable decorated with FragDepth must be declared using the Output storage class.

The variable decorated with FragDepth must be declared as a scalar 32-bit floating-point value.

FragStencilRefEXT

Decorating a variable with the FragStencilRefEXT built-in d= ecoration will make that variable contain the stencil reference value for all samples covered by the fragment. This value will be used as the stencil reference value used in stencil testing.

To write to FragStencilRefEXT, a shader must declare the StencilRefReplacingEXT execution mode. If a shader declares the StencilRefReplacingEXT execution mode= and there is an execution path through the shader that does not set FragStencilRefEXT, then the fragment=E2=80=99s stencil referen= ce value is undefined for executions of the shader that take that path.

The FragStencilRefEXT decoration m= ust be used only within fragment shaders.

The variable decorated with FragStencilRefEXT must be declared using the Output storage class.

The variable decorated with FragStencilRefEXT must be declared as a scalar integer value. Only the least significant s bits of the integer value of = the variable decorated with FragStencilRefEXT are considered for stencil te= sting, where s is the number of bits in the stencil framebuffer a= ttachment, and higher order bits are discarded.

FrontFacing

Decorating a variable with the FrontFacing built-in decorat= ion will make that variable contain whether the fragment is front or back facing. This variable is non-zero if the current fragment is considered to be part of a front-facing polygon primitive or of a non-polygon primitive and is zero if the fragment is considered to be part of a back-facing polygon primitive.

The FrontFacing decoration must be used only within fragment shaders.

The variable decorated with FrontFacing must be declared using the Input storage class.

The variable decorated with FrontFacing must be declared as a boolean.

FullyCoveredEXT

Decorating a variable with the FullyCoveredEXT built-in dec= oration will make that variable indicate whether the fragment pixel square is fully covered by the generating primitive. This variable is non-zero if conservative rasterization is enabled and the current fragment pixel square is fully covered by the generating primitive, and is zero if the fragment is not covered or partially covered, or conservative rasterization is disabled.

The FullyCoveredEXT decoration mus= t be used only within fragment shaders and the FragmentFullyCoveredEXT capability must be declared.

The variable decorated with FullyCoveredEXT must be declared using the Input storage class.

The variable decorated with FullyCoveredEXT must be declared as a boolean.

If the implementation supports VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= conservativeRasterizationPostDepthCoverage and the PostDepthCoverage execution mode is specified the SampleMask built-in input vari= able will reflect the coverage after the early per-fragment depth and stencil tests are applied. If VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= conservativeRasterizationPostDepthCoverage is not supported the PostDepthCoverage execution mode must not be specified.

GlobalInvocationId

Decorating a variable with the GlobalInvocationId built-in = decoration will make that variable contain the location of the current invocation within the global workgroup. Each component is equal to the index of the local workgroup multiplied by the size of the local workgroup plus LocalInvocationId.

The GlobalInvocationId decoration = must be used only within compute shaders.

The variable decorated with GlobalInvocationId must be declared using the Input storage class.

The variable decorated with GlobalInvocationId must be declared as a three-component vector of 32-bit integers.

HelperInvocation

Decorating a variable with the HelperInvocation built-in de= coration will make that variable contain whether the current invocation is a helper invocation. This variable is non-zero if the current fragment being shaded is a helper invocation and zero otherwise. A helper invocation is an invocation of the shader that is produced to satisfy internal requirements such as the generation of derivatives.

The HelperInvocation decoration mu= st be used only within fragment shaders.

The variable decorated with HelperInvocation must be declared using the Input storage class.

The variable decorated with HelperInvocation must be declared as a boolean.

Note

It is very likely that a helper invocation will have a value of SampleMask fragment shader input value that is zero.

InvocationId

Decorating a variable with the InvocationId built-in decora= tion will make that variable contain the index of the current shader invocation in a geometry shader, or the index of the output patch vertex in a tessellation control shader.

In a geometry shader, the index of the current shader invocation ranges = from zero to the number of instances declared in the shader minus one. If the instance count of the geometry shader is one or is not specified, then InvocationId will be zero.

The InvocationId decoration must be used only within tessellation control and geometry shaders.

The variable decorated with InvocationId must be declared using the Input storage class.

The variable decorated with InvocationId must be declared as a scalar 32-bit integer.

InstanceIndex

Decorating a variable with the InstanceIndex built-in decor= ation will make that variable contain the index of the instance that is being processe= d by the current vertex shader invocation. InstanceIndex begins at the firstInstance paramet= er to vkCmdDraw or vkCmdDrawIndexed or at th= e firstInstance member of a structure consumed by vkCmdDrawIndirect = or vkCmdDrawIndexedIndirect.

The InstanceIndex decoration must<= /strong> be used only within vertex shaders.

The variable decorated with InstanceIndex must be declared using the Input storage class.

The variable decorated with InstanceIndex must be declared as a scalar 32-bit integer.

Layer

Decorating a variable with the Layer built-in decoration wi= ll make that variable contain the select layer of a multi-layer framebuffer attachment.<= /p>

In a vertex, tessellation evaluation, or geometry shader, any variable decorated with Layer can be writ= ten with the framebuffer layer index to which the primitive produced by that shader will be directed.

The last active vertex processing stage (in pipeline order) con= trols the Layer that is used. Outputs in previous shader stages are not used, even if the last stage fail= s to write the Layer.

If the last active vertex processing stage shader entry point=E2=80=99s = interface does not include a variable decorated with Layer, then the fir= st layer is used. If a vertex processing stage shader entry point=E2=80=99s interface include= s a variable decorated with Layer, it mus= t write the same value to Layer for all output vertices of a given primitive. If the Layer value is less than 0 or greater than or equal to = the number of layers in the framebuffer, then primitives may still be rasterized, fragment shaders may be execu= ted, and the framebuffer values for all layers are undefined.

The Layer decoration must= be used only within vertex, tessellation evaluation, geometry, and fragment shaders.

In a vertex, tessellation evaluation, or geometry shader, any variable decorated with Layer must be declared using the Output storage class. If such a variable is also decorated with ViewportRelativeNV, = then the ViewportIndex is added to the layer that is used for rendering= and that is made available in the fragment shader. If the shader writes to a variable decorated ViewportMaskNV, t= hen the layer selected has a different value for each viewport a primitive is rendered to.

In a fragment shader, a variable decorated with Layer conta= ins the layer index of the primitive that the fragment invocation belongs to.

In a fragment shader, any variable decorated with Layer must be declared using the Input storage class.

Any variable decorated with Layer = must be declared as a scalar 32-bit integer.

LocalInvocationId

Decorating a variable with the LocalInvocationId built-in d= ecoration will make that variable contain the location of the current compute shader invocation within the local workgroup. Each component ranges from zero through to the size of the workgroup in tha= t dimension minus one.

The LocalInvocationId decoration m= ust be used only within compute shaders.

The variable decorated with LocalInvocationId must be declared using the Input storage class.

The variable decorated with LocalInvocationId must be declared as a three-component vector of 32-bit integers.

Note

If the size of the workgroup in a particular dimension is one, then the LocalInvocationId in that dimension will be zero. If the workgroup is effectively two-dimensional, then LocalInvocationId.z will be zero. If the workgroup is effectively one-dimensional, then both LocalInvocationId.y and LocalInvocationId.z will = be zero.

LocalInvocationIndex

Decorating a variable with the LocalInvocationIndex built-i= n decoration will make that variable contain a one-dimensional representation of LocalInvocationId. This is computed as:

LocalInvocationInd=
ex =3D
    LocalInvocationId.z * WorkgroupSize.x * WorkgroupSize.y +
    LocalInvocationId.y * WorkgroupSize.x +
    LocalInvocationId.x;

The LocalInvocationIndex decoration must be used only within compute shaders.

+ The variable decorated with LocalInvocationIndex must be declared using the Input storage class.

+ The variable decorated with LocalInvocationIndex must be declared as a scalar 32-bit integer.

NumSubgroups

Decorating a variable with the NumSubgroups built-in decora= tion will make that variable contain the number of subgroups in the local workgroup.<= /p>

The NumSubgroups decoration must be used only within compute shaders.

The variable decorated with NumSubgroups must be declared using the Input storage class.

The object decorated with NumSubgroups must be declared as a scalar 32-bit integer.

NumWorkgroups

Decorating a variable with the NumWorkgroups built-in decor= ation will make that variable contain the number of local workgroups that are part of the dispatch that the invocation belongs to. Each component is equal to the values of the workgroup count parameters passed into the dispatch commands.

The NumWorkgroups decoration must<= /strong> be used only within compute shaders.

The variable decorated with NumWorkgroups must be declared using the Input storage class.

The variable decorated with NumWorkgroups must be declared as a three-component vector of 32-bit integers.

PatchVertices

Decorating a variable with the PatchVertices built-in decor= ation will make that variable contain the number of vertices in the input patch being processed by the shader. A single tessellation control or tessellation evaluation shader can read patches of differing sizes, so the value of the PatchVertices = variable may differ between patches.

The PatchVertices decoration must<= /strong> be used only within tessellation control and tessellation evaluation shaders.

The variable decorated with PatchVertices must be declared using the Input storage class.

The variable decorated with PatchVertices must be declared as a scalar 32-bit integer.

PointCoord

Decorating a variable with the PointCoord built-in decorati= on will make that variable contain the coordinate of the current fragment within the point being rasterized, normalized to the size of the point with origin in the upper left corner of the point, as described in Basic Point Rasterization. If the primitive the fragment shader invocation belongs to is not a point, then the variable decorated with PointCoord contains an undefi= ned value.

The PointCoord decoration must be used only within fragment shaders.

The variable decorated with PointCoord must be declared using the Input storage class.

The variable decorated with PointCoord must be declared as two-component vector of 32-bit floating-point values.

Note

Depending on how the point is rasterized, PointCoord may never reach (0,0) or (1,1).

PointSize

Decorating a variable with the PointSize built-in decoratio= n will make that variable contain the size of point primitives. The value written to the variable decorated with PointSize by = the last vertex processing stage in the pipeline is used as the framebuffer-space size of points produced by rasterization.

The PointSize decoration must be used only within vertex, tessellation control, tessellation evaluation, and geometry shaders.

In a vertex shader, any variable decorated with PointSize <= strong class=3D"purple">must be declared using the Output storage class.

In a tessellation control, tessellation evaluation, or geometry shader, = any variable decorated with PointSize mus= t be declared using either the Input or Output storage class.

Any variable decorated with PointSize must be declared as a scalar 32-bit floating-point value.

Note

When PointSize decorates a variable in the Input storage class, it contains the data written to the output variable decorated with PointSize from the previous shader stage.

Position

Decorating a variable with the Position built-in decoration= will make that variable contain the position of the current vertex. In the last vertex processing stage, the value of the variable decorated with Position is used in subsequent primitive assembly, clippi= ng, and rasterization operations.

The Position decoration must be used only within vertex, tessellation control, tessellation evaluation, and geometry shaders.

In a vertex shader, any variable decorated with Position must be declared using the Output storage class.

In a tessellation control, tessellation evaluation, or geometry shader, = any variable decorated with Position must= not be declared in a storage class other than Input or Output.

Any variable decorated with Position must be declared as a four-component vector of 32-bit floating-point values.

Note

When Position decorates a variable in the Input storage class, it contains the data written to the output variable decorated with Position from the previous shader stage.

PositionPerViewNV

Decorating a variable with the PositionPerViewNV built-in d= ecoration will make that variable contain the position of the current vertex, for eac= h view.

The PositionPerViewNV decoration m= ust be used only within vertex, tessellation control, tessellation evaluation, and geometry shaders.

In a vertex shader, any variable decorated with PositionPerViewNV<= /code> must be declared using the Output storage class.

In a tessellation control, tessellation evaluation, or geometry shader, = any variable decorated with PositionPerViewNV must not be declared in a storage class other than input or output.

Any variable decorated with PositionPerViewNV must be declared as an array of four-component vector of 32-bit floating-point values with at leas= t as many elements as the maximum view in the subpass=E2=80=99s view mask plu= s one. The array must be indexed by a constant o= r specialization constant.

Elements of the array correspond to views in a multiview subpass, and th= ose elements corresponding to views in the view mask of the subpass the shader is compiled against will be used as the position value for those views. For the final vertex processing stage in the pipeline, values written to an output variable decorated with PositionPerViewNV are used in s= ubsequent primitive assembly, clipping, and rasterization operations, as with Position. PositionPerViewNV output in an earlier vertex processing stage= is available as an input in the subsequent vertex processing stage.

If a shader is compiled against a subpass that has the VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX bit se= t, then the position values for each view must no= t differ in any component other than the X component. If the values do differ, one will be chosen in an implementation-dependent manner.

PrimitiveId

Decorating a variable with the PrimitiveId built-in decorat= ion will make that variable contain the index of the current primitive.

The index of the first primitive generated by a drawing command is zero,= and the index is incremented after every individual point, line, or triangle primitive is processed.

For triangles drawn as points or line segments (see Polygon Mode), the primitive index is incremented only once, even if multiple points or lines are eventually drawn.

Variables decorated with PrimitiveId are reset to zero betw= een each instance drawn.

Restarting a primitive topology using primitive restart has no effect on= the value of variables decorated with PrimitiveId.

In tessellation control and tessellation evaluation shaders, it will con= tain the index of the patch within the current set of rendering primitives that correspond to the shader invocation.

In a geometry shader, it will contain the number of primitives presented= as input to the shader since the current set of rendering primitives was started.

In a fragment shader, it will contain the primitive index written by the geometry shader if a geometry shader is present, or with the value that would have been presented as input to the geometry shader had it been present.

If a geometry shader is present and the fragment shader reads from an in= put variable decorated with PrimitiveId, then the geometry shader = must write to an output variable decorated with PrimitiveId in all = execution paths.

The PrimitiveId decoration must be used only within fragment, tessellation control, tessellation evaluation, and geometry shaders.

In a tessellation control or tessellation evaluation shader, any variabl= e decorated with PrimitiveId must be declared using the Input storage class.

In a geometry shader, any variable decorated with PrimitiveId must be declared using either the Input or Output storage= class.

In a fragment shader, any variable decorated with PrimitiveId must be declared using the Input storage class, and either the G= eometry or Tessellation capability must= also be declared.

Any variable decorated with PrimitiveId must be declared as a scalar 32-bit integer.

Note

When the PrimitiveId decoration is applied to an output var= iable in the geometry shader, the resulting value is seen through the PrimitiveId<= /code> decorated input variable in the fragment shader.

SampleId

Decorating a variable with the SampleId built-in decoration= will make that variable contain the zero-based index of the sample the invocation corresponds to. SampleId ranges from zero to the number of samples in the fram= ebuffer minus one. If a fragment shader entry point=E2=80=99s interface includes an input vari= able decorated with SampleId, Sample Shadi= ng is considered enabled with a minSampleShading value of 1.0.

The SampleId decoration must be used only within fragment shaders.

The variable decorated with SampleId must be declared using the Input storage class.

The variable decorated with SampleId must be declared as a scalar 32-bit integer.

SampleMask

Decorating a variable with the SampleMask built-in decorati= on will make any variable contain the sample coverage mask for the current fragment shader invocation.

A variable in the Input storage class decorated with = SampleMask will contain a bitmask of the set of samples covered by the primitive generating the fragment during rasterization. It has a sample bit set if and only if the sample is considered covered for this fragment shader invocation. SampleMask[] is an array of integers. Bits are mapped to samples in a manner where bit B of mask M (SampleMask[M]) corresponds to sample 32 = =C3=97 M + B.

When state specifies multiple fragment shader invocations for a given fragment, the sample mask for any single fragment shader invocation specifies the subset of the covered samples for the fragment that correspon= d to the invocation. In this case, the bit corresponding to each covered sample will be set in exactly one fragment shader invocation.

If the PostDepthCoverage execution mode is specified, the sample is considered covered if and only i= f the sample is covered by the primitive and the sample passes the early per-fragment tests. Otherwise the sample is considered covered if the sample is covered by the primitive, regardless of the result of the fragment tests.

A variable in the Output storage class decorated with SampleMask is an array of integers forming a bit array in a manner similar an input variable decorated with SampleMask, but where each bit represe= nts coverage as computed by the shader. Modifying the sample mask by writing zero to a bit of SampleMask causes the sample to be considered uncovered. If this variable is also decorated with OverrideCoverageNV, th= e fragment coverage is replaced with the sample mask bits set in the shader otherwise the fragment coverage is ANDed with the bits of the = sample mask. If the fragment shader is being evaluated at any frequency other than per-fragment, bits of the sample mask not corresponding to the current fragment shader invocation are ignored. This array must be sized in the fragment = shader either implicitly or explicitly, to be no larger than the implementation-dependent maximum sample-mask (as an array of 32-bit elements), determined by the maximum number of samples. If a fragment shader entry point=E2=80=99s interface includes an output var= iable decorated with SampleMask, the sample mask will be undefined f= or any array elements of any fragment shader invocations that fail to assign a value. If a fragment shader entry point=E2=80=99s interface does not include an ou= tput variable decorated with SampleMask, the sample mask has no eff= ect on the processing of a fragment.

The SampleMask decoration must be used only within fragment shaders.

Any variable decorated with SampleMask must be declared using either the Input or Output storage class.

Any variable decorated with SampleMask must be declared as an array of 32-bit integers.

SamplePosition

Decorating a variable with the SamplePosition built-in deco= ration will make that variable contain the sub-pixel position of the sample being shaded. The top left of the pixel is considered to be at coordinate (0,0) and the bottom right of the pixel is considered to be at coordinate (1,1). If a fragment shader entry point=E2=80=99s interface includes an input vari= able decorated with SamplePosition, Sample Shading is considered enabled with a minSampleShading valu= e of 1.0.

The SamplePosition decoration must= be used only within fragment shaders.

The variable decorated with SamplePosition must be declared using the Input storage class. If the current pipeline uses custom sample locations the value of any variable decorated with the SamplePosi= tion built-in decoration is undefined.

The variable decorated with SamplePosition must be declared as a two-component vector of 32-bit floating-point values.

SubgroupId

Decorating a variable with the SubgroupId built-in decorati= on will make that variable contain the index of the subgroup within the local workgroup. This variable is in range [0, NumSubgroups-1].

The SubgroupId decoration must be used only within compute shaders.

The variable decorated with SubgroupId must be declared using the Input storage class.

The variable decorated with SubgroupId must be declared as a scalar 32-bit integer.

SubgroupEqMask

Decorating a variable with the SubgroupEqMask builtin decor= ation will make that variable contain the subgroup mask of the current subgro= up invocation. The bit corresponding to the SubgroupLocalInvocationId is set = in the variable decorated with SubgroupEqMask. All other bits are set to zero.

The variable decorated with SubgroupEqMask must be declared using the Input storage class.

The variable decorated with SubgroupEqMask must be declared as a four-component vector of 32-bit integer values.

SubgroupEqMaskKHR is an alias of SubgroupEqMask.

SubgroupGeMask

Decorating a variable with the SubgroupGeMask builtin decor= ation will make that variable contain the subgroup mask of the current subgro= up invocation. The bits corresponding to the invocations greater than or equal to SubgroupLocalInvocationId through SubgroupSize-1 = are set in the variable decorated with SubgroupGeMask. All other bits are set to zero.

The variable decorated with SubgroupGeMask must be declared using the Input storage class.

The variable decorated with SubgroupGeMask must be declared as a four-component vector of 32-bit integer values.

SubgroupGeMaskKHR is an alias of SubgroupGeMask.

SubgroupGtMask

Decorating a variable with the SubgroupGtMask builtin decor= ation will make that variable contain the subgroup mask of the current subgro= up invocation. The bits corresponding to the invocations greater than SubgroupLocalInvocationId through SubgroupSize-1 = are set in the variable decorated with SubgroupGtMask. All other bits are set to zero.

The variable decorated with SubgroupGtMask must be declared using the Input storage class.

The variable decorated with SubgroupGtMask must be declared as a four-component vector of 32-bit integer values.

SubgroupGtMaskKHR is an alias of SubgroupGtMask.

SubgroupLeMask

Decorating a variable with the SubgroupLeMask builtin decor= ation will make that variable contain the subgroup mask of the current subgro= up invocation. The bits corresponding to the invocations less than or equal to SubgroupLocalInvocationId are set in the variable decorated wi= th SubgroupLeMask. All other bits are set to zero.

The variable decorated with SubgroupLeMask must be declared using the Input storage class.

The variable decorated with SubgroupLeMask must be declared as a four-component vector of 32-bit integer values.

SubgroupLeMaskKHR is an alias of SubgroupLeMask.

SubgroupLtMask

Decorating a variable with the SubgroupLtMask builtin decor= ation will make that variable contain the subgroup mask of the current subgro= up invocation. The bits corresponding to the invocations less than SubgroupLocalInvocationId are set in the variable decorated wi= th SubgroupLtMask. All other bits are set to zero.

The variable decorated with SubgroupLtMask must be declared using the Input storage class.

The variable decorated with SubgroupLtMask must be declared as a four-component vector of 32-bit integer values.

SubgroupLtMaskKHR is an alias of SubgroupLtMask.

SubgroupLocalInvocationId

Decorating a variable with the SubgroupLocalInvocationId bu= iltin decoration will make that variable contain the index of the invocation within the subgroup. This variable is in range [0,SubgroupSize-1].

The variable decorated with SubgroupLocalInvocationId must be declared using the Input storage class.

The variable decorated with SubgroupLocalInvocationId must be declared as a scalar 32-bit integer.

SubgroupSize

Decorating a variable with the SubgroupSize builtin decorat= ion will make that variable contain the implementation-dependent maximum number of invocations in a subgroup. The maximum number of invocations that an implementation can support per subgroup is 128.

The variable decorated with SubgroupSize must be declared using the Input storage class.

The variable decorated with SubgroupSize must be declared as a scalar 32-bit integer.

TessCoord

Decorating a variable with the TessCoord built-in decoratio= n will make that variable contain the three-dimensional (u,v,w) barycentric coordinate of the tessellated vertex within the patch. u, v, and w are in the range [0,1] and vary = linearly across the primitive being subdivided. For the tessellation modes of Quads or IsoLines, = the third component is always zero.

The TessCoord decoration must be used only within tessellation evaluation shaders.

The variable decorated with TessCoord must be declared using the Input storage class.

The variable decorated with TessCoord must be declared as three-component vector of 32-bit floating-point values.

TessLevelOuter

Decorating a variable with the TessLevelOuter built-in deco= ration will make that variable contain the outer tessellation levels for the current patch.

In tessellation control shaders, the variable decorated with TessLevelOuter can be writte= n to which controls the tessellation factors for the resulting patch. These values are used by the tessellator to control primitive tessellation and can be read by tessellation evaluatio= n shaders.

In tessellation evaluation shaders, the variable decorated with TessLevelOuter can read the = values written by the tessellation control shader.

The TessLevelOuter decoration must= be used only within tessellation control and tessellation evaluation shaders.

In a tessellation control shader, any variable decorated with TessLevelOuter must be decla= red using the Output storage class.

In a tessellation evaluation shader, any variable decorated with TessLevelOuter must be decla= red using the Input storage class.

Any variable decorated with TessLevelOuter must be declared as an array of size four, containing 32-bit floating-point values.

TessLevelInner

Decorating a variable with the TessLevelInner built-in deco= ration will make that variable contain the inner tessellation levels for the current patch.

In tessellation control shaders, the variable decorated with TessLevelInner can be writte= n to, which controls the tessellation factors for the resulting patch. These values are used by the tessellator to control primitive tessellation and can be read by tessellation evaluatio= n shaders.

In tessellation evaluation shaders, the variable decorated with TessLevelInner can read the = values written by the tessellation control shader.

The TessLevelInner decoration must= be used only within tessellation control and tessellation evaluation shaders.

In a tessellation control shader, any variable decorated with TessLevelInner must be decla= red using the Output storage class.

In a tessellation evaluation shader, any variable decorated with TessLevelInner must be decla= red using the Input storage class.

Any variable decorated with TessLevelInner must be declared as an array of size two, containing 32-bit floating-point values.

VertexIndex

Decorating a variable with the VertexIndex built-in decorat= ion will make that variable contain the index of the vertex that is being processed by the current vertex shader invocation. For non-indexed draws, this variable begins at the firstVertex parameter to vkCmdDraw or the firstVertex membe= r of a structure consumed by vkCmdDrawIndirect and increments by one = for each vertex in the draw. For indexed draws, its value is the content of the index buffer for the vertex plus the vertexOffset parameter to vk= CmdDrawIndexed or the vertexOffset member of the structure consumed by vkCmdDrawIndexedIndirect.

The VertexIndex decoration must be used only within vertex shaders.

The variable decorated with VertexIndex must be declared using the Input storage class.

The variable decorated with VertexIndex must be declared as a scalar 32-bit integer.

Note

VertexIndex starts at the same starting value for each inst= ance.

ViewIndex

The ViewIndex decoration can be applied to a shader input which will be filled with the index of the view that is being processed by the current shader invocation.

If multiview is enabled in the render pass, this value will be one of th= e bits set in the view mask of the subpass the pipeline is compiled against. If multiview is not enabled in the render pass, this value will be zero.

The ViewIndex decoration must not be used within compute shaders.

The variable decorated with ViewIndex must be declared using the Input storage class.

The variable decorated with ViewIndex must be declared as a scalar 32-bit integer.

ViewportIndex

Decorating a variable with the ViewportIndex built-in decor= ation will make that variable contain the index of the viewport.

In a vertex, tessellation evaluation, or geometry shader, the variable decorated with ViewportIndex can= be written to with the viewport index to which the primitive produced by that shader will be directed.

The selected viewport index is used to select the viewport transform and scissor rectangle.

The last active vertex processing stage (in pipeline order) con= trols the ViewportIndex that is used. Outputs in previous shader stages are not used, even if the last stage fail= s to write the ViewportIndex.

If the last active vertex processing stage shader entry point=E2=80=99s = interface does not include a variable decorated with ViewportIndex, then= the first viewport is used. If a vertex processing stage shader entry point=E2=80=99s interface include= s a variable decorated with ViewportIndex, it must write the same value to ViewportIndex for all output vertices of a given primitive.

The ViewportIndex decoration must<= /strong> be used only within vertex, tessellation evaluation, geometry, and fragment shaders.

In a vertex, tessellation evaluation, or geometry shader, any variable decorated with ViewportIndex must be declared using the Output storage class.

In a fragment shader, the variable decorated with ViewportIndex contains the viewport index of the primitive that the fragment invocation belongs to.

In a fragment shader, any variable decorated with ViewportIndex must be declared using the Input storage class.

Any variable decorated with ViewportIndex must be declared as a scalar 32-bit integer.

ViewportMaskNV

Decorating a variable with the ViewportMaskNV built-in deco= ration will make that variable contain the viewport mask.

In a vertex, tessellation evaluation, or geometry shader, the variable decorated with ViewportMaskNV can be written to with the mask = of which viewports the primitive produced by that shader will directed.

The ViewportMaskNV variable must be an array that has =E2=8C=88(VkPhysicalDeviceLimits::max= Viewports / 32)=E2=8C=89 elements. When a shader writes to this variable, bit B of element M controls whether = a primitive is emitted to viewport 32 =C3=97 M +B. The viewports indicated by the mask are used to select the viewport transform and scissor rectangle that a primitive will be transformed by.

The last active vertex processing stage (in pipeline order) con= trols the ViewportMaskNV that is used. Outputs in previous shader stages are not used, even if the last stage fail= s to write the ViewportMaskNV. When ViewportMaskNV is written by the final vertex processing = stage, any variable decorated with ViewportIndex in the fragment shad= er will have the index of the viewport that was used in generating that fragment.

If a vertex processing stage shader entry point=E2=80=99s interface incl= udes a variable decorated with ViewportMaskNV, it must write the same value to ViewportMaskNV for all output vertices of a given primitive= .

The ViewportMaskNV decoration must= be used only within vertex, tessellation evaluation, and geometry shaders.

Any variable decorated with ViewportMaskNV must be declared using the Output storage class.

Any variable decorated with ViewportMaskNV must be declared as an array of 32-bit integers.

ViewportMaskPerViewNV

Decorating a variable with the ViewportMaskPerViewNV built-= in decoration will make that variable contain the mask of viewports primitives are broadcast to, for each view.

The ViewportMaskPerViewNV decoration must be used only within vertex, tessellation control, tessellation evaluation, and geometry shaders.

Any variable decorated with ViewportMaskPerViewNV must be declared using the Output storage class.

The value written to an element of ViewportMaskPerViewNV in= the last vertex processing stage is a bitmask indicating which viewports the primitive will be directed to. The primitive will be broadcast to the viewport corresponding to each non-zero bit of the bitmask, and that viewport index is used to select the viewport transform and scissor rectangle, for each view. The same values must be written to all ve= rtices in a given primitive, or else the set of viewports used for that primitive is undefined.

Any variable decorated with ViewportMaskPerViewNV must be declared as an array of scalar 32-bit integers with at least as many elements as the maximum view in the subpass=E2=80=99s view mask plus one. The array must be indexed by a constant o= r specialization constant.

Elements of the array correspond to views in a multiview subpass, and th= ose elements corresponding to views in the view mask of the subpass the shader is compiled against will be used as the viewport mask value for those views= . ViewportMaskPerViewNV output in an earlier vertex processing s= tage is not available as an input in the subsequent vertex processing stage.

Although ViewportMaskNV is an array, ViewportMaskPerV= iewNV is not a two-dimensional array. Instead, ViewportMaskPerViewNV is limited to 32 viewports.

WorkgroupId

Decorating a variable with the WorkgroupId built-in decorat= ion will make that variable contain the global workgroup that the current invocation is a member of. Each component ranges from a base value to a base + cou= nt value, based on the parameters passed into the dispatch commands.

The WorkgroupId decoration must be used only within compute shaders.

The variable decorated with WorkgroupId must be declared using the Input storage class.

The variable decorated with WorkgroupId must be declared as a three-component vector of 32-bit integers.

WorkgroupSize

Decorating an object with the WorkgroupSize built-in decora= tion will make that object contain the dimensions of a local workgroup. If an object is decorated with the WorkgroupSize decoration, t= his must take precedence over any execution mode set for LocalSize.

The WorkgroupSize decoration must<= /strong> be used only within compute shaders.

The object decorated with WorkgroupSize must be a specialization constant or a constant.

The object decorated with WorkgroupSize must be declared as a three-component vector of 32-bit integers.

14.5. Shader Resource Interface

When a shader stage accesses buffer or image resources, as described in = the Resource Descriptors section, the shader resource variables must be matched with the pipeline layout that is provided at pipeline creation time.

The set of shader resources that form the shader resource interface<= /em> for a stage are the variables statically used by OpEntryPoint with t= he storage class of Uniform, UniformConstant, or PushConstant. For the fragment shader, this includes the frag= ment input attachment interface.

The shader resource interface consists of two sub-interfaces: the push constant interface and the descriptor set interface.

14.5.1. Push Constant Interface

The shader variables defined with a storage class of PushConstant<= /code> that are statically used by the shader entry points for the pipeline define the push constant interface. They must be:

  • typed as OpTypeStruct,

  • identified with a Block decoration, and

  • laid out explicitly using the Offset, ArrayStride, and MatrixStride decorations as specified in Offset and Stride Assignment.

There must be no more than one push co= nstant block statically used per shader entry point.

Each variable in a push constant block must be placed at an Offset such that the entire constant value is entirely contained within the VkPushConstantRange for each OpEntryPoint that uses it, and the stageFlags for that range must specify the appropriate VkShaderStageFlagBits for that stage. The Offset decoration for any variable in a push constant bloc= k must not cause the space required for that variable to extend outside the range [0, maxPushConstantsSize).

Any variable in a push constant block that is declared as an array must only be accessed with dynamically uniform indices.

14.5.2. Descriptor Set Interface

The descriptor set interface is comprised of the shader variabl= es with the storage class of Uniform or UniformConstant (incl= uding the variables in the fragment input attachment interface) that are statically used by the shader entry points for the pipeline.

These variables must have Descri= ptorSet and Binding decorations specified, which are assigned and matched with the VkDescriptorSetLayout objects in the pipeline layout as descri= bed in DescriptorSet and Binding Assignment.

Variables identified with the UniformConstant storage class= are used only as handles to refer to opaque resources. Such variables must be typed as OpT= ypeImage, OpTypeSampler, OpTypeSampledImage, or an array of one of these types.

The Sampled Type of an OpTypeImage declaration must match the same basic data type as the corresponding resource, or the values obtained by reading or sampling from this image are undefined.

The Image Format of an OpTypeImage declaration must not be Unknown, for variables which are used for OpImageRea= d, OpImageSparseRead, or OpImageWrite operations, ex= cept under the following conditions:

  • For OpImageWrite, if the shaderStorageImageWriteWitho= utFormat feature is enabled and the shader module declares the StorageImageWriteWithoutFormat capability.

  • For OpImageRead or OpImageSparseRead, if the shaderStorageImageReadWithoutFormat feature is enabled and the shader module declares the StorageImageReadWithoutFormat capability.

The Image Format of an OpTypeImage declaration must not be Unknown, for variables which are used for OpAtomic* operations.

Variables identified with the Uniform storage class are use= d to access transparent buffer backed resources. Such variables must be:

Variables identified with the StorageBuffer storage class a= re used to access transparent buffer backed resources. Such variables must be:

  • typed as OpTypeStruct, or an array of this type,

  • identified with a Block decoration, and

  • laid out explicitly using the Offset, ArrayStride, and MatrixStride decorations as specified in Offset and Stride Assignment.

The Offset decoration for any member of a Block-decorated variable in the Uniform storage class must not cause the space required for that variable to extend outside the range [0, maxUniformBufferRange). The Offset decoration for any member of a Block-d= ecorated variable in the StorageBuffer storage class mu= st not cause the space required for that variable to extend outside the range [0, maxStorageBufferRange).

Variables identified with a storage class of UniformConstant and a decoration of InputAttachmentIndex mu= st be declared as described in Fragment Input Attachment Interface.

SPIR-V variables decorated with a descriptor set and binding that identi= fy a combined image sampler descriptor can have a type of OpTypeImage, OpTypeSampler (Sampled=3D1), or OpTypeSampledImage.

Arrays of any of these types can be in= dexed with constant integral expressions. The following features must be enabled an= d capabilities must be declared in order to index such arrays with dynamically uniform or non-uniform indices:

  • Storage images (except storage texel buffers and input attachments):

    • Dynamically uniform: shaderStorageImageArrayDynamicIndexing= and StorageImageArrayDynamicIndexing

    • Non-uniform: shaderStorageImageArrayNonUniformIndexing and StorageImageArrayNonUniformIndexingEXT

  • Storage texel buffers:

    • Dynamically uniform: shaderStorageTexelBufferArrayDynamicIndexing<= /code> and StorageTexelBufferArrayDynamicIndexingEXT

    • Non-uniform: shaderStorageTexelBufferArrayNonUniformIndexing and StorageTexelBufferArrayNonUniformIndexingEXT

  • Input attachments:

    • Dynamically uniform: shaderInputAttachmentArrayDynamicIndexing and InputAttachmentArrayDynamicIndexingEXT

    • Non-uniform: shaderInputAttachmentArrayNonUniformIndexing a= nd InputAttachmentArrayNonUniformIndexingEXT

  • Sampled images (except uniform texel buffers):

    • Dynamically uniform: shaderSampledImageArrayDynamicIndexing= and SampledImageArrayDynamicIndexing

    • Non-uniform: shaderSampledImageArrayNonUniformIndexing and SampledImageArrayNonUniformIndexingEXT

  • Uniform texel buffers:

    • Dynamically uniform: shaderUniformTexelBufferArrayDynamicIndexing<= /code> and UniformTexelBufferArrayDynamicIndexingEXT

    • Non-uniform: shaderUniformTexelBufferArrayNonUniformIndexing and UniformTexelBufferArrayNonUniformIndexingEXT

  • Uniform buffers:

    • Dynamically uniform: shaderUniformBufferArrayDynamicIndexing and UniformBufferArrayDynamicIndexing

    • Non-uniform: shaderUniformBufferArrayNonUniformIndexing and UniformBufferArrayNonUniformIndexingEXT

  • Storage buffers:

    • Dynamically uniform: shaderStorageBufferArrayDynamicIndexing and StorageBufferArrayDynamicIndexing

    • Non-uniform: shaderStorageBufferArrayNonUniformIndexing and StorageBufferArrayNonUniformIndexingEXT

If an instruction loads from or stores to a resource (including atomics = and image instructions) and the resource descriptor being accessed is not dynamically uniform, then the corresponding non-uniform indexing feature must be enabled and the capability must be declared. If an instruction loads from or stores to a resource (including atomics and image instructions) and the resource descriptor being accessed is not uniform, then the corresponding dynamic indexing or non-uniform feature must be enabled and the capabilit= y must be declared.

If sampler Y=E2=80=99CBCR conversion is enabled, t= he combined image sampler must be indexed only by constant integral= expressions when aggregated into arrays in shader code, irrespective of the shaderSampledImageArrayDynamicIndexing feature.

Table 19. Shader Resource and Descriptor Type Corr= espondence
Resource type Descriptor Type

sam= pler

VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER<= /code>

sam= pled image

VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER<= /code>

sto= rage image

VK_DESCRIPTOR_TYPE_STORAGE_IMAGE

com= bined image sampler

VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER

uni= form texel buffer

VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER

sto= rage texel buffer

VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER

uni= form buffer

VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC<= /code>

sto= rage buffer

VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC<= /code>

inp= ut attachment

VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT

Table 20. Shader Resource and Storage Class Corres= pondence
Resource type Storage Class Type Decoration(s)1

sam= pler

UniformConstant

OpTypeSampler

sam= pled image

UniformConstant

OpTypeImage (Sampled=3D1)

sto= rage image

UniformConstant

OpTypeImage (Sampled=3D2)

com= bined image sampler

UniformConstant

OpTypeSampledImage
OpTypeImage (Sampled=3D1)
OpTypeSampler

uni= form texel buffer

UniformConstant

OpTypeImage (Dim=3DBuffer, Sample= d=3D1)

sto= rage texel buffer

UniformConstant

OpTypeImage (Dim=3DBuffer, Sample= d=3D2)

uni= form buffer

Uniform

OpTypeStruct

Block, Offset, (ArrayStride), (Ma= trixStride)

storage buffer

Uniform

OpTypeStruct

BufferBlock, Offset, (ArrayStride), (MatrixStride)

StorageBuffer

Block, Offset, (ArrayStride), (Ma= trixStride)

inp= ut attachment

UniformConstant

OpTypeImage (Dim=3DSubpassData, S= ampled=3D2)

InputAttachmentIndex

1

in addition to DescriptorSet and Binding

14.5.3. DescriptorSet and Bin= ding Assignment

A variable decorated with a DescriptorSet decoration of s and a Binding decoration of b indicates th= at this variable is associated with the VkDescriptorSetLayoutBind= ing that has a binding equal to b in pSetLayo= uts[s] that was specified in VkPipelineLayoutCreateInfo.

DescriptorSet decoration values mu= st be between zero and maxBoundDescriptorSets minus one, inclusive. Binding decoration values can be any 32-bit unsigned integer value, as described in Descriptor Set Layout. Each descriptor set has its own binding name space.

If the Binding decoration is used with an array, the entire= array is assigned that binding value. The array must be a single-dimensional ar= ray and size of the array must be no larger than the number of descriptors in the binding. If the array is runtime-sized, then array elements greater than or equal to the size of that binding in the bound descriptor set must not be used. If the array is runtime-sized, the runtimeDescriptorArray feat= ure must be enabled and the RuntimeDesc= riptorArrayEXT capability must be declared. The index of each element of the array is referred to as the arrayEleme= nt. For the purposes of interface matching and descriptor set operations, if a resource variable is not an array, it is treated as if it has an arrayElement of zero.

There is a limit on the number of resources of each type that can be accessed by a pipeline stage as shown in Shader Resource Limits. The =E2=80=9CResources Per Stage=E2=80=9D column gives the limit on the num= ber each type of resource that can be statically used f= or an entry point in any given stage in a pipeline. The =E2=80=9CResource Types=E2=80=9D column lists which resource types are = counted against the limit. Some resource types count against multiple limits.

The pipeline layout may include descri= ptor sets and bindings which are not referenced by any variables statically used by the entry points for the shader stages in the binding=E2=80=99s stageFlags.

However, if a variable assigned to a given DescriptorSet an= d Binding is statically used by the entry point for a shader sta= ge, the pipeline layout must contain a descriptor= set layout binding in that descriptor set layout and for that binding number, and that binding=E2=80= =99s stageFlags must include the = appropriate VkShaderStageFlagBits for that stage. The variable must be of a valid resource = type determined by its SPIR-V type and storage class, as defined in Shader Resource and Storage Class Correspondence. The descriptor set layout binding must be= of a corresponding descriptor type, as defined in Shader Resource and Descriptor Type Correspondence.

Note

There are no limits on the number of shader variables that can have overlapping set and binding values in a shader; but which resources are statically used has an impact. If any shader variable identifying a resource is statically used in a shader, then the underlying descriptor bound at the declared set and binding must support the declared type in the shader when the shader executes.

If multiple shader variables are declared with the same set and binding values, and with the same underlying descriptor type, they can all be statically used within the same shader. However, accesses are not automatically synchronized, and Aliased decorations should be used to avoid data hazards (see section 2.18.2 Aliasing in the SPIR-V specification).

If multiple shader variables with the same set and binding values are declared in a single shader, but with different declared types, where any o= f those are not supported by the relevant bound descriptor, that shader can only be executed if the variables with the unsupported type are not statically used.

A noteworthy example of using multiple statically-used shader variables sharing the same descriptor set and binding values is a descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER that has multiple corresponding shader variables in the UniformConstant storage = class, where some could be OpTypeImage, some could be OpTypeSam= pler (Sampled=3D1), and some could be OpTypeSampledImage.

Table 21. Shader Resource Limits
Resources per Stage Resource Types

maxPerStageDescriptorSamplers or maxPerStageDescriptorUpdateAfterBindSamplers

sam= pler

com= bined image sampler

maxPerStageDescriptorSampledImages or maxPerStageDescriptorUpdateAfterBindSampledImages

sam= pled image

com= bined image sampler

uni= form texel buffer

maxPerStageDescriptorStorageImages or maxPerStageDescriptorUpdateAfterBindStorageImages

sto= rage image

sto= rage texel buffer

maxPerStageDescriptorUniformBuffers or maxPerStageDescriptorUpdateAfterBindUniformBuffers

uni= form buffer

uni= form buffer dynamic

maxPerStageDescriptorStorageBuffers or maxPerStageDescriptorUpdateAfterBindStorageBuffers

sto= rage buffer

sto= rage buffer dynamic

maxPerStageDescriptorInputAttachments or maxPerStageDescriptorUpdateAfterBindInputAttachments

inp= ut attachment1

1

Input attachments can only be used in = the fragment shader stage

14.5.4. Offset and Stride Assignment=

All variables with a storage class of PushConstant or Uniform must be explicitly laid out using the Offset, ArrayStride, and MatrixStride decorations. There are two different layouts requirements depending on the specific resources.

Standard Uniform Buffer Layout

The base alignment of the type of an OpTypeStruct = member of is defined recursively as follows:

  • A scalar of size N has a base alignment of N.

  • A two-component vector, with components of size N, has a base alignment of 2 N.

  • A three- or four-component vector, with components of size N, has a base alignment of 4 N.

  • An array has a base alignment equal to the base alignment of its element type, rounded up to a multiple of 16.

  • A structure has a base alignment equal to the largest base alignment of any of its members, rounded up to a multiple of 16.

  • A row-major matrix of C columns has a base ali= gnment equal to the base alignment of a vector of C matrix components= .

  • A column-major matrix has a base alignment equal to the base alignment of the matrix column type.

A member is defined to improperly straddle if either of the fol= lowing are true:

  • It is a vector with total size less than or equal to 16 bytes, and has Offset decorations placing its first byte at F and its last byte at L, where floor(F / 16)= !=3D floor(L / 16).

  • It is a vector with total size greater than 16 bytes and has its Offset decorations placing its first byte at a non-integer mul= tiple of 16.

Every member of an OpTypeStruct with storage class of Uniform and a decoration of Block (uniform buffers) must be laid out according to the following rules:

  • The Offset decoration of a scalar, an array, a structure, o= r a matrix must be a multiple of its base ali= gnment.

  • The Offset decoration of a vector = must be an integer multiple of the base alignment of its scalar component type, and must not improperly straddle, as defined above.

  • Any ArrayStride or MatrixStride decoration must be an integer multiple of the base alignment of the array or matrix from above.

  • The Offset decoration of a member = must not place it between the end of a structure or an array and the next multiple of the base alignment of that structure or array.

  • The numeric order of Offset decorations need not follow mem= ber declaration order.

Note

The std140 layout in GLSL satisfies these rules.

Standard Storage Buffer Layout

Member variables of an OpTypeStruct with a storage class of PushConstant (push constants), or a storage class of Uni= form with a decoration of BufferBlock (storage buffers) , or a storage class of StorageBuffer with a decoration of Block must be laid out as above, except for array and structure base alignment which do not need to be rounded up t= o a multiple of 16.

Note

The std430 layout in GLSL satisfies these rules.

15. Image Operations

15.1. Image Operations Overview

Image Operations are steps performed by SPIR-V image instructions, where those instructions which take an OpTypeImage (representing a VkImageView) or OpTypeSampledImage (representing = a (VkImageView, VkSampler) pair) and texel coordina= tes as operands, and return a value based on one or more neighboring texture elements (texels) in the image.

Note

Texel is a term which is a combination of the words texture and element. Early interactive computer graphics supported texture operations on textures, a small subset of the image operations on images described here. The discrete samples remain essentially equivalent, however, so we retain the historical term texel to refer to them.

SPIR-V Image Instructions include the following functionality:

  • OpImageSample* and OpImageSparseSample* read o= ne or more neighboring texels of the image, and filter the texel values based on the state of the sampler.

    • Instructions with ImplicitLod in the name determine the LOD used in the sampling operation based on the coordinates used in neighboring fragments.

    • Instructions with ExplicitLod in the name determine the LOD used in the sampling operation based on additional coordinates.

    • Instructions with Proj in the name apply homogeneous projection to the coordinates.

  • OpImageFetch and OpImageSparseFetch return a s= ingle texel of the image. No sampler is used.

  • OpImage*Gather and OpImageSparse*= Gather read neighboring texels and return a single component of each.

  • OpImageRead (and OpImageSparseRead) and = OpImageWrite read and write, respectively, a texel in the image. No sampler is used.

  • Instructions with Dref in the name apply depth comparison on the texel values.

  • Instructions with Sparse in the name additionally return a sparse residency code.

15.1.1. Texel Coordinate Systems

Images are addressed by texel coordinates. There are three texel coordinate systems:

  • normalized texel coordinates [0.0, 1.0]

  • unnormalized texel coordinates [0.0, width / height /= depth)

  • integer texel coordinates [0, width / height / depth)=

SPIR-V OpImageFetch, OpImageSparseFetch, OpImageRead, OpImageSparseRead, and OpImageWrite instructions = use integer texel coordinates. Other image instructions can use either n= ormalized or unnormalized texel coordinates (selected by the unnormalizedCoordinates state of = the sampler used in the instruction), but there are limitations on what operations, image state, and sampler state is supported. Normalized coordinates are logically converted to unnormalized as part = of image operations, and certain steps are only performed on normalized coordinates. The array layer coordinate is always treated as unnormalized even when othe= r coordinates are normalized.

Normalized texel coordinates are referred to as (s,t,= r,q,a), with the coordinates having the following meanings:

  • s: Coordinate in the first dimension of an ima= ge.

  • t: Coordinate in the second dimension of an im= age.

  • r: Coordinate in the third dimension of an ima= ge.

    • (s,t,r) are interpreted as a direction vector = for Cube images.

  • q: Fourth coordinate, for homogeneous (project= ive) coordinates.

  • a: Coordinate for array layer.

The coordinates are extracted from the SPIR-V operand based on the dimensionality of the image variable and type of instruction. For Proj instructions, the components are in order (s, [t,] [r= ,] q) with t and r being conditionally present based on the Dim of t= he image. For non-Proj instructions, the coordinates are (s [,t] [,r] [,= a]), with t and r being conditionally present based on the Dim of the im= age and a being conditionally present based on the Arrayed property of t= he image. Projective image instructions are not supported on Arrayed ima= ges.

Unnormalized texel coordinates are referred to as (u,= v,w,a), with the coordinates having the following meanings:

  • u: Coordinate in the first dimension of an ima= ge.

  • v: Coordinate in the second dimension of an im= age.

  • w: Coordinate in the third dimension of an ima= ge.

  • a: Coordinate for array layer.

Only the u and v coo= rdinates are directly extracted from the SPIR-V operand, because only 1D and 2D (non-Arrayed) dimension= alities support unnormalized coordinates. The components are in order (u [,v]), with v being conditionally present when the dimensionality is 2D. When normalized coordinates are converted to unnormalized coordinates, all four coordinates are used.

Integer texel coordinates are referred to as (i,j,k,l= ,n), and the first four in that order have the same meanings as unnormalized texel coordinates. They are extracted from the SPIR-V operand in order (i, = [,j], [,k], [,l]), with j and k conditionally present based on the Dim of the image, and l conditionally present based on the Arrayed= property of the image. n is the sample index and is taken from the Sample image opera= nd.

For all coordinate types, unused coordinates are assigned a value of zer= o.

3D"vulkantexture0=
Figure 3. Texel Coordinate Systems

The Texel Coordinate Systems - For the example shown of an 8=C3=974 texe= l two dimensional image.

  • Normalized texel coordinates:

    • The s coordinate goes from 0.0 to 1.0, left to= right.

    • The t coordinate goes from 0.0 to 1.0, top to = bottom.

  • Unnormalized texel coordinates:

    • The u coordinate goes from -1.0 to 9.0, left t= o right. The u coordinate within the range 0.0 to 8.0 is w= ithin the image, otherwise it is within the border.

    • The v coordinate goes from -1.0 to 5.0, top to= bottom. The v coordinate within the range 0.0 to 4.0 is w= ithin the image, otherwise it is within the border.

  • Integer texel coordinates:

    • The i coordinate goes from -1 to 8, left to ri= ght. The i coordinate within the range 0 to 7 addresse= s texels within the image, otherwise it addresses a border texel.

    • The j coordinate goes from -1 to 5, top to bot= tom. The j coordinate within the range 0 to 3 addresse= s texels within the image, otherwise it addresses a border texel.

  • Also shown for linear filtering:

    • Given the unnormalized coordinates (u,v), the = four texels selected are i0j0, i1j0, i0j1, and i1j1.

    • The weights =CE=B1 and =CE= =B2.

    • Given the offset =CE=94i and =CE=94j, the four texels selected by the offset are i0j'0, i1j'0, i= 0j'1, and i1j'1.

Note

For formats with reduced-resolution channels, =CE=94<= sub>i and =CE=94j are relative to the resolution= of the highest-resolution channel, and therefore may be divided by two relative to the unnormalized coordinate space of the lower-resolution channels.

3D"v=
Figure 4. Texel Coordinate Systems

The Texel Coordinate Systems - For the example shown of an 8=C3=974 texe= l two dimensional image.

  • Texel coordinates as above. Also shown for nearest filtering:

    • Given the unnormalized coordinates (u,v), the = texel selected is ij.

    • Given the offset =CE=94i and =CE=94j, the texel selected by the offset is ij'.

15.2. Conversion Formulas

editing-note

(Bill) These Conversion Formulas will likely move to Section 2.7 Fixed-P= oint Data Conversions (RGB to sRGB and sRGB to RGB) and section 2.6 Numeric Representation and Computation (RGB to Shared Exponent and Shared Exponent to RGB)

15.2.1. RGB to Shared Exponent Conversion

An RGB color (red, green, blue) is transformed= to a shared exponent color (redshared, greenshared, blu= eshared, expshared) as follows:

First, the components (red, green, blue) are c= lamped to (redclamped, greenclamped, blueclamped) as:

redclamped =3D max(0, min(sharedexpma= x, red))

greenclamped =3D max(0, min(sharedexp= max, green))

blueclamped =3D max(0, min(sharedexpm= ax, blue))

Where:

\[\begin{aligned} N & =3D 9 & \text{number of mantissa bits per compon= ent} \\ B & =3D 15 & \text{exponent bias} \\ E_{max} & =3D 31 & \text{maximum possible biased exponent v= alue} \\ sharedexp_{max} & =3D \frac{(2^N-1)}{2^N} \times 2^{(E_{max}-B)} \end{aligned}\]
Note

NaN, if supported, is handled as in = IEEE 754-2008 minNum() and maxNum(). That is the result is a NaN is mapped to zero.

The largest clamped component, maxclamped<= /span> is determined:

maxclamped =3D max(redclamped, = greenclamped, blueclamped)

A preliminary shared exponent exp' is computed= :

\[\begin{aligned} exp' =3D \begin{cases} \left \lfloor \log_2(max_{clamped}) \right \rfloor + (B+1) & \text{for}\ max_{clamped} > 2^{-(B+1)} \\ 0 & \text{for}\ max_{clamped} \leq 2^{-(B+1)} \end{cases} \end{aligned}\]

The shared exponent expshared is co= mputed:

\[\begin{aligned} max_{shared} =3D \left \lfloor { \frac{max_{clamped}}{2^{(exp'-B-N)}} + \frac{1}{2} } \right \rfloor \end{aligned}\]
\[\begin{aligned} exp_{shared} =3D \begin{cases} exp' & \text{for}\ 0 \leq max_{shared} < 2^N \\ exp'+1 & \text{for}\ max_{shared} =3D 2^N \end{cases} \end{aligned}\]

Finally, three integer values in the range 0 t= o 2N are computed:

\[\begin{aligned} red_{shared} & =3D \left \lfloor { \frac{red_{clamped}}{2^{(exp_{shared}-B-N)}}+ \frac{1}{2} } \right \rfloor \\ green_{shared} & =3D \left \lfloor { \frac{green_{clamped}}{2^{(exp_{shared}-B-N)}}+ \frac{1}{2} } \right \rfloor \\ blue_{shared} & =3D \left \lfloor { \frac{blue_{clamped}}{2^{(exp_{shared}-B-N)}}+ \frac{1}{2} } \right \rfloor \end{aligned}\]

15.2.2. Shared Exponent to RGB

A shared exponent color (redshared, green<= sub>shared, blueshared, expshared) is transformed to an RGB color (red, green, blue) as follows:

\(red =3D red_{shared} \times {2^{(exp_{shared}-B-N)}}\)

\(green =3D green_{shared} \times {2^{(exp_{shared}-B-N)}}\)

\(blue =3D blue_{shared} \times {2^{(exp_{shared}-B-N)}}\)

Where:

N =3D 9 (number of mantissa bits per component= )

B =3D 15 (exponent bias)

15.3. Texel Input Operations

Texel input instructions are SPIR-V image instructions that rea= d from an image. Texel input operations are a set of steps that are performed on st= ate, coordinates, and texel values while processing a texel input instruction, and which are common to some or all texel input instructions. They include the following steps, which are performed in the listed order:<= /p>

For texel input instructions involving multiple texels (for sampling or gathering), these steps are applied for each texel that is used in the instruction. Depending on the type of image instruction, other steps are conditionally performed between these steps or involving multiple coordinate or texel values.

If Chroma Reconstruction is implicit= , Texel Filtering instead takes place during chroma reconstruction, before sampler Y=E2=80=99CBCR conversion occurs.

15.3.1. Texel Input Validation Operati= ons

Texel input validation operations inspect instruction/image/sam= pler state or coordinates, and in certain circumstances cause the texel value to be replaced or become undefined. There are a series of validations that the texel undergoes.

Instruction/Sampler/Image View Val= idation

There are a number of cases where a SPIR-V instruction can mismatch with the sampler, the image view, or both. There are a number of cases where the sampler can<= /strong> mismatch with the image view. In such cases the value of the texel returned is undefined.

These cases include:

  • The sampler borderColor is an integer type and the image vi= ew format is not one of the VkFormat integer types = or a stencil component of a depth/stencil format.

  • The sampler borderColor is a float type and the image view format is not one of the VkFormat float types or= a depth component of a depth/stencil format.

  • The sampler borderColor is one of the opaque black colors (VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK or VK_BORDER_COLOR_INT_OPAQUE_BLACK) and the image view VkComponentSwizzle for any of the VkComponentMapping components is not VK_COMPONENT_SWIZZLE_IDENTITY.

  • The VkImageLayout of any subresource in the image vie= w does not match that specified in VkDescriptorImageInfo::<= code>imageLayout used to write the image descriptor.

  • If the instruction is OpImageRead or OpImageSparseRea= d and the shaderStorageImageReadWithoutFormat feature is not enabled, or= the instruction is OpImageWrite and the shaderStorageImageWriteWithoutFormat feature is not enabled, t= hen the SPIR-V Image Format must be compatible with the image view=E2=80=99s format.

  • The sampler unnormalizedCoordinates is VK_TRUE= and any of the limitations of unnormalized coordinates are violated.

  • The SPIR-V instruction is one of the OpImage*Dref* instructions and the sampler compareEnable is VK_FALSE

  • The SPIR-V instruction is not one of the OpImage*Dref= * instructions and the sampler compareEnable is VK_TRUE

  • The SPIR-V instruction is one of the OpImage*Dref* instructions and the image view format is not one of the depth/stencil formats with a depth component, or the image view aspect is not VK_IMAGE_ASPECT_DEPTH_BIT.

  • The SPIR-V instruction=E2=80=99s image variable=E2=80=99s properties are= not compatible with the image view:

    • Rules for viewType:

      • VK_IMAGE_VIEW_TYPE_1D must have Dim =3D 1D, Arrayed =3D 0, MS =3D 0.

      • VK_IMAGE_VIEW_TYPE_2D must have Dim =3D 2D, Arrayed =3D 0.

      • VK_IMAGE_VIEW_TYPE_3D must have Dim =3D 3D, Arrayed =3D 0, MS =3D 0.

      • VK_IMAGE_VIEW_TYPE_CUBE must have Dim =3D Cube, Arrayed =3D 0, MS =3D 0.

      • VK_IMAGE_VIEW_TYPE_1D_ARRAY must have Dim =3D 1D, Arrayed =3D 1, MS =3D 0.

      • VK_IMAGE_VIEW_TYPE_2D_ARRAY must have Dim =3D 2D, Arrayed =3D 1.

      • VK_IMAGE_VIEW_TYPE_CUBE_ARRAY must= have Dim =3D Cube, Arrayed =3D 1, MS =3D 0.

    • If the image was created with VkImageCreateInfo::= samples equal to VK_SAMPLE_COUNT_1_BIT, the instruction must have MS =3D 0.

    • If the image was created with VkImageCreateInfo::= samples not equal to VK_SAMPLE_COUNT_1_BIT, the instruction must have MS =3D 1.

Only OpImageSample* and OpImageSparseSample* <= strong class=3D"purple">can be used with a sampler that enables sampler Y=E2=80=99CBCR conversion.

OpImageFetch, OpImageSparseFetch, OpImag= e*Gather, and OpImageSparse*Gather mus= t not be used with a sampler that enables sampler Y'CBCR conversion<= /a>.

Integer Texel Coordinate = Validation

Integer texel coordinates are validated against the size of the image le= vel, and the number of layers and number of samples in the image. For SPIR-V instructions that use integer texel coordinates, this is performed directly on the integer coordinates. For instructions that use normalized or unnormalized texel coordinates, thi= s is performed on the coordinates that result after conversion to integer texel coordinates.

If the integer texel coordinates do not satisfy all of the conditions

0 =E2=89=A4 i < ws

0 =E2=89=A4 j < hs

0 =E2=89=A4 k < ds

0 =E2=89=A4 l < layers

0 =E2=89=A4 n < samples

where:

ws =3D width of the image level

hs =3D height of the image level

ds =3D depth of the image level

layers =3D number of layers in the image

samples =3D number of samples per texel in the= image

then the texel fails integer texel coordinate validation.

There are four cases to consider:

  1. Valid Texel Coordinates

    • If the texel coordinates pass validation (that is, the coordinates lie within the image),

    then the texel value comes from the value in image memory.

  2. Border Texel

    • If the texel coordinates fail validation, and

    • If the read is the result of an image sample instruction or image gather instruction, and

    • If the image is not a cube image,

    then the texel is a border texel and texel replacement is performed.

  3. Invalid Texel

    • If the texel coordinates fail validation, and

    • If the read is the result of an image fetch instruction, image read instruction, or atomic instruction,

    then the texel is an invalid texel and texel replacement is performed.

  4. Cube Map Edge or Corner

    Otherwise the texel coordinates lie on the borders along the edges and corners of a cube map image, and Cube map edge handling is performed.

Cube Map Edge Handling

If the texel coordinates lie on the borders along the edges and corners = of a cube map image, the following steps are performed. Note that this only occurs when using VK_FILTER_LINEAR filteri= ng within a mip level, since VK_FILTER_NEAREST is treated as usin= g VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE.

  • Cube Map Edge Texel

    • If the texel lies along the border in either only i or only j

    then the texel lies along an edge, so the coordinates (i,j) and the array layer l are transformed to select the adjac= ent texel from the appropriate neighboring face.

  • Cube Map Corner Texel

    • If the texel lies along the border in both i a= nd j

    then the texel lies at a corner and there is no unique neighboring face = from which to read that texel. The texel should be replaced by the avera= ge of the three values of the adjacent texels in each incident face. However, implementations may replace the = cube map corner texel by other methods, subject to the constraint that if the three available samples have the same value, the replacement texel also has that value.

Sparse Validation

If the texel reads from an unbound region of a sparse image, the texel i= s a sparse unbound texel, and processing continues with texel replacement.

Layout Validation

If all planes of a disjoint multi-planar image are not= in the same image layout when the image is sampled with sampler Y=E2=80=99CBCR con= version, the result of texel reads is undefined.

15.3.2. Format Conversion

Texels undergo a format conversion from the VkFormat of th= e image view to a vector of either floating point or signed or unsigned integer components, with the number of components based on the number of components present in the format.

  • Color formats have one, two, three, or four components, according to the format.

  • Depth/stencil formats are one component. The depth or stencil component is selected by the aspectMask o= f the image view.

Each component is converted based on its type and size (as defined in th= e Format Definition section for each VkFormat), using the appropriate equations in 16-Bit Floating-Point Numbers, Unsigned 11-Bit Floating-Point Numbers, Unsigned 10-Bit Floating-Point Numbers, Fixed-Point Data Conversion, and Shared Exponent to RGB. Signed integer components smaller than 32 bits are sign-extended.

If the image format is sRGB, the color components are first converted as= if they are UNORM, and then sRGB to linear conversion is applied to the R, G, and B components as described in the =E2=80=9CsRGB EOTF=E2=80=9D section of= the Khronos Data Format Specification. The A component, if present, is unchanged.

If the image view format is block-compressed, then the texel value is fi= rst decoded, then converted based on the type and number of components defined by the compressed format.

15.3.3. Texel Replacement

A texel is replaced if it is one (and only one) of:

  • a border texel,

  • an invalid texel, or

  • a sparse unbound texel.

Border texels are replaced with a value based on the image format and th= e borderColor of the sampler. The border color is:

Table 22. Border Color B=
Sampler borderColor Corresponding Border Color<= /th>

VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK

B =3D (0.0, 0.0, 0.0, 0.0)

VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK

B =3D (0.0, 0.0, 0.0, 1.0)

VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE

B =3D (1.0, 1.0, 1.0, 1.0)

VK_BORDER_COLOR_INT_TRANSPARENT_BLACK

B =3D (0, 0, 0, 0)

VK_BORDER_COLOR_INT_OPAQUE_BLACK

B =3D (0, 0, 0, 1)

VK_BORDER_COLOR_INT_OPAQUE_WHITE

B =3D (1, 1, 1, 1)

Note

The names VK_BORDER_COLOR_*_TRANSPARENT_BLACK, VK_BORDER_COLOR_*_OPAQUE_BLACK, and VK_BORDER_COLOR_*_OPAQUE_WHITE are meant to describe which com= ponents are zeros and ones in the vocabulary of compositing, and are not meant to imply that the numerical value of VK_BORDER_COLOR_INT_OPAQUE_WHITE is a saturating value for integers.

This is substituted for the texel value by replacing the number of components in the image format

Table 23. Border Texel Components After Replacemen= t
Texel Aspect or Format Component Assignment

Dep= th aspect

D =3D Br

Ste= ncil aspect

S =3D Br

One= component color format

Cr =3D Br

Two= component color format

Crg =3D (Br,Bg)

Thr= ee component color format

Crgb =3D (Br,Bg,Bb)

Fou= r component color format

Crgba =3D (Br,Bg,Bb,Ba)

The value returned by a read of an invalid texel is undefined, unless th= at read operation is from a buffer resource and the robustBufferAccess feature is enabled. In that case, an invalid texel is replaced as described by the robustBufferAccess featu= re.

If the VkPhysicalDeviceSparseProperties::residencyNonResidentStrict property is VK_TRUE, a sparse unbound texel is replaced with 0= or 0.0 values for integer and floating-point components of the image format, respectively.

If residencyNonResidentStrict is VK_FALSE, the= value of the sparse unbound texel is undefined.

15.3.4. Depth Compare Operation=

If the image view has a depth/stencil format, the depth component is selected by the aspectMask, and the operation is a Dref<= /code> instruction, a depth comparison is performed. The value of the result D is 1= .0 if the result of the compare operation is true, and 0.0 otherwise. The compare operation is selected by the compareOp member of t= he sampler.

\[\begin{aligned} D & =3D 1.0 & \begin{cases} D_{\textit{ref}} \leq D & \text{for LEQUAL} \\ D_{\textit{ref}} \geq D & \text{for GEQUAL} \\ D_{\textit{ref}} < D & \text{for LESS} \\ D_{\textit{ref}} > D & \text{for GREATER} \\ D_{\textit{ref}} =3D D & \text{for EQUAL} \\ D_{\textit{ref}} \neq D & \text{for NOTEQUAL} \\ \textit{true} & \text{for ALWAYS} \\ \textit{false} & \text{for NEVER} \end{cases} \\ D & =3D 0.0 & \text{otherwise} \end{aligned}\]

where, in the depth comparison:

Dref =3D shaderOp.Dref (= from optional SPIR-V operand)

D (texel depth value)

15.3.5. Conversion to RGBA

The texel is expanded from one, two, or three to four components based o= n the image base color:

Table 24. Texel Color After Conversion To RGBA
Texel Aspect or Format RGBA Color

Dep= th aspect

Crgba =3D (D,0,0,one)

Ste= ncil aspect

Crgba =3D (S,0,0,one)

One= component color format

Crgba =3D (Cr,0,0,one)

Two= component color format

Crgba =3D (Crg,0,one)

Thr= ee component color format

Crgba =3D (Crgb,one)

Fou= r component color format

Crgba =3D Crgba

where one =3D 1.0f for floating-point formats = and depth aspects, and one =3D 1 for integer formats and stencil aspects= .

15.3.6. Component Swizzle

All texel input instructions apply a swizzle based on:

The swizzle can rearrange the componen= ts of the texel, or substitute zero and one for any components. It is defined as follows for the R component, and operates similarly for th= e other components.

\[\begin{aligned} C'_{rgba}[R] & =3D \begin{cases} C_{rgba}[R] & \text{for RED swizzle} \\ C_{rgba}[G] & \text{for GREEN swizzle} \\ C_{rgba}[B] & \text{for BLUE swizzle} \\ C_{rgba}[A] & \text{for ALPHA swizzle} \\ 0 & \text{for ZERO swizzle} \\ one & \text{for ONE swizzle} \\ C_{rgba}[R] & \text{for IDENTITY swizzle} \end{cases} \end{aligned}\]

where:

\[\begin{aligned} C_{rgba}[R] & \text{is the RED component} \\ C_{rgba}[G] & \text{is the GREEN component} \\ C_{rgba}[B] & \text{is the BLUE component} \\ C_{rgba}[A] & \text{is the ALPHA component} \\ one & =3D 1.0\text{f} & \text{for floating point component= s} \\ one & =3D 1 & \text{for integer components} \end{aligned}\]

For each component this is applied to, the VK_COMPONENT_SWIZZLE_IDENTITY swizzle selects the correspondin= g component from Crgba.

If the border color is one of the VK_BORDER_COLOR_*_OPAQUE_BLACK enums and the VkComponentSwizzle is not VK_COMPONEN= T_SWIZZLE_IDENTITY for all components (or the equivalent identity mapping), the value of the texel after swizzle is undefined.

15.3.7. Sparse Residency

OpImageSparse* instructions return a structure which includ= es a residency code indicating whether any texels accessed by the instr= uction are sparse unbound texels. This code can be interpreted by the OpImageSparseTexelsResident instruction which converts the residency code to a boolean value.

15.3.8. Chroma Reconstruction

In some color models, the color representation is defined in terms of monochromatic light intensity (often called =E2=80=9Cluma=E2=80=9D) and col= or differences relative to this intensity, often called =E2=80=9Cchroma=E2=80=9D. It is common for color models other than RGB to represent the chroma channels at lower spatial resolution than the luma channel. This approach is used to take advantage of the eye=E2=80=99s lower spatial sensitivity to color compared with its sensitivity to brightness. Less commonly, the same approach is used with additive color, since the green channel dominates the eye=E2=80=99s sensitivity to light intensity an= d the spatial sensitivity to color introduced by red and blue is lower.

Lower-resolution channels are =E2=80=9Cdownsampled=E2=80=9D by resizing = them to a lower spatial resolution than the channel representing luminance. The process of reconstructing a full color value for texture access involve= s accessing both chroma and luma values at the same location. To generate the color accurately, the values of the lower-resolution channels at the location of the luma samples must be reconstructed from the lower-resolution sample locations, an operation known here as =E2=80=9Cchro= ma reconstruction=E2=80=9D irrespective of the actual color model.

The location of the chroma samples relative to the luma coordinates is determined by the xChromaOffset and yChromaOffset= members of the VkSamplerYcbcrConversionCreateInfo = structure used to create the sampler Y=E2=80=99CBCR conversion.

The following diagrams show the relationship between unnormalized (u= ,v) coordinates and (i,j) integer texel positions in the luma= channel (shown in black, with circles showing integer sample positions) and the texel coordinates of reduced-resolution chroma channels, shown as crosses in red.=

Note

If the chroma values are reconstructed at the locations of the luma samp= les by means of interpolation, chroma samples from outside the image bounds are needed; these are determined according to Wrap= ping Operation. These diagrams represent this by showing the bounds of the =E2=80=9Cchroma = texel=E2=80=9D extending beyond the image bounds, and including additional chroma sample positions where required for interpolation. The limits of a sample for NEAREST sampling is shown as a grid= .

3D"chromasamples
Figure 5. 422 downsampling, xChromaOffset=3DCOSITED_EV= EN
3D"chromasamples
Figure 6. 422 downsampling, xChromaOffset=3DMIDPOINT
=3D"chromasamples
Figure 7. 420 downsampling, xChromaOffset=3DCOSITED_EV= EN, yChromaOffset=3DCOSITED_EVEN
3D"chromasamples
Figure 8. 420 downsampling, xChromaOffset=3DMIDPOINT, = yChromaOffset=3DCOSITED_EVEN
3D"chromasamples
Figure 9. 420 downsampling, xChromaOffset=3DCOSITED_EV= EN, yChromaOffset=3DMIDPOINT
3D"chromasample=
Figure 10. 420 downsampling, xChromaOffset=3DMIDPOINT,= yChromaOffset=3DMIDPOINT

Reconstruction is implemented in one of two ways:

If the format of the image that is to be sampled sets VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTIO= N_EXPLICIT_BIT, or the VkSamplerYcbcrConversionCreateInfo=E2=80=99s forceExplicitReconstruction is set to VK_TRUE, re= construction is performed as an explicit step independent of filtering, described in the Explicit Reconstruction section.

If the format of the image that is to be sampled does not set VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTIO= N_EXPLICIT_BIT and if the VkSamplerYcbcrConversionCreateInfo=E2=80=99s forceExplicitReconstruction is set to VK_FALSE, r= econstruction is performed as an implicit part of filtering prior to color model conversion, with no separate post-conversion texel filtering step, as described in the Implicit Reconstruction section.

Explicit Reconstruction
  • If the chromaFilter member of the VkSamplerYcbcrConversionCreateInfo = structure is VK_FILTER_NEAREST:

    • If the format=E2=80=99s R and B channels are reduced in resolution in ju= st width by a factor of two relative to the G channel (i.e. this is a =E2=80=9C_422=E2=80=9D format), the \(\tau_{ijk}[level]\) valu= es accessed by texel filtering are reconstructed as follows:

      \[\begin{aligned} \tau_R'(i, j) & =3D \tau_R(\lfloor{i\times 0.5}\rfloor, j)[level] \\ \tau_B'(i, j) & =3D \tau_B(\lfloor{i\times 0.5}\rfloor, j)[level] \end{aligned}\]
    • If the format=E2=80=99s R and B channels are reduced in resolution in wi= dth and height by a factor of two relative to the G channel (i.e. this is a =E2=80=9C_420=E2=80=9D format), the \(\tau_{ijk}[level]\) va= lues accessed by texel filtering are reconstructed as follows:

      \[\begin{aligned} \tau_R'(i, j) & =3D \tau_R(\lfloor{i\times 0.5}\rfloor, \lfloor{j\times= 0.5}\rfloor)[level] \\ \tau_B'(i, j) & =3D \tau_B(\lfloor{i\times 0.5}\rfloor, \lfloor{j\times= 0.5}\rfloor)[level] \end{aligned}\]
      Note

      xChromaOffset and yChromaOffset have no effect= if chromaFilter is VK_FILTER_NEAREST for explicit re= construction.

  • If the chromaFilter member of the VkSamplerYcbcrConversionCreateInfo = structure is VK_FILTER_LINEAR:

    • If the format=E2=80=99s R and B channels are reduced in resolution in ju= st width by a factor of two relative to the G channel (i.e. this is a =E2=80=9C422=E2=80=9D format):

      • If xChromaOffset is VK_CHROMA_LOCATION_COSITED_EVEN:

        \[\tau_{RB}'(i,j) =3D \begin{cases} \tau_{RB}(\lfloor{i\times 0.5}\rfloor,j)[level], & 0.5 \times i =3D \lf= loor{0.5 \times i}\rfloor\\ 0.5\times\tau_{RB}(\lfloor{i\times 0.5}\rfloor,j)[level] + \\ 0.5\times\tau_{RB}(\lfloor{i\times 0.5}\rfloor + 1,j)[level], & 0.5 \ti= mes i \neq \lfloor{0.5 \times i}\rfloor \end{cases}\]
      • If xChromaOffset is VK_CHROMA_LOCATION_MIDPOINT:

        \[\tau_{RB}(i,j)' =3D \begin{cases} 0.25 \times \tau_{RB}(\lfloor{i\times 0.5}\rfloor - 1,j)[level] + \\ 0.75 \times \tau_{RB}(\lfloor{i\times 0.5}\rfloor,j)[level], & 0.5 \tim= es i =3D \lfloor{0.5 \times i}\rfloor\\ 0.75 \times \tau_{RB}(\lfloor{i\times 0.5}\rfloor,j)[level] + \\ 0.25 \times \tau_{RB}(\lfloor{i\times 0.5}\rfloor + 1,j)[level], & 0.5 = \times i \neq \lfloor{0.5 \times i}\rfloor \end{cases}\]
    • If the format=E2=80=99s R and B channels are reduced in resolution in wi= dth and height by a factor of two relative to the G channel (i.e. this is a =E2=80=9C420=E2=80=9D format), a similar relationship applies. Due to the number of options, these formulae are expressed more concisely as follows:

      xChromaOffset<= /th> =CE=B4i

      COSITED_EVEN

      0

      MIDPOINT

      0.5=

      yChromaOffset<= /th> =CE=B4j

      COSITED_EVEN

      0

      MIDPOINT

      0.5=

      \[\begin{aligned} \tau_{RB}'(i,j) =3D &\\ &\tau_{RB}(\lfloor 0.5\times(i-\delta_i)\rfloor, \lfloor 0.5\times(j-\d= elta_j)\rfloor)[level] && \times (1 - (0.5\times(i-\delta_i) - \lfloor 0.5\times(i-\delta_= i)\rfloor)) && \times (1 - (0.5\times(j-\delta_j) - \lfloor 0.5\times(j-\delta_= j)\rfloor)) +\\ &\tau_{RB}(1+\lfloor 0.5\times(i-\delta_i)\rfloor, \lfloor 0.5\times(j-= \delta_j)\rfloor)[level] && \times (0.5\times(i-\delta_i) - \lfloor 0.5\times(i-\delta_i)\rf= loor) && \times (1 - (0.5\times(j-\delta_j) - \lfloor 0.5\times(j-\delta_= j)\rfloor)) +\\ &\tau_{RB}(\lfloor 0.5\times(i-\delta_i)\rfloor, 1+\lfloor 0.5\times(j-= \delta_j)\rfloor)[level] && \times (1 - (0.5\times(i-\delta_i) - \lfloor 0.5\times(i-\delta_= i)\rfloor)) && \times (0.5\times(j-\delta_j) - \lfloor 0.5\times(j-\delta_j)\rf= loor) +\\ &\tau_{RB}(1+\lfloor 0.5\times(i-\delta_i)\rfloor, 1+\lfloor 0.5\times(= j-\delta_j)\rfloor)[level] && \times (0.5\times(i-\delta_i) - \lfloor 0.5\times(i-\delta_i)\rf= loor) && \times (0.5\times(j-\delta_j) - \lfloor 0.5\times(j-\delta_j)\rf= loor) \end{aligned}\]
Note

In the case where the texture itself is bilinearly interpolated as descr= ibed in Texel Filtering, thus requiring four full-color samples for the filtering operation, and where the reconstructio= n of these samples uses bilinear interpolation in the chroma channels due to chromaFilter=3DVK_FILTER_LINEAR, up to nine chrom= a samples may be required, depending on the sample location.

Implicit Reconstruction

Implicit reconstruction takes place by the samples being interpolated, a= s required by the filter settings of the sampler, except that chromaFilter takes precedence for the chroma samples.

If chromaFilter is VK_FILTER_NEAREST, an imple= mentation may behave as if xChromaOffset and yChromaOffset were= both VK_CHROMA_LOCATION_MIDPOINT, irrespective of the values set.

Note

This will not have any visible effect if the locations of the luma sampl= es coincide with the location of the samples used for rasterization.

The sample coordinates are adjusted by the downsample factor of the chan= nel (such that, for example, the sample coordinates are divided by two if the channel has a downsample factor of two relative to the luma channel):

\[\begin{aligned} u_{RB}' (422/420) &=3D \begin{cases} 0.5\times (u + 0.5), & \textrm{xChromaOffset =3D COSITED}\_\textrm= {EVEN} \\ 0.5\times u, & \textrm{xChromaOffset =3D MIDPOINT} \end{cases} \\ v_{RB}' (420) &=3D \begin{cases} 0.5\times (v + 0.5), & \textrm{yChromaOffset =3D COSITED}\_\textrm= {EVEN} \\ 0.5\times v, & \textrm{yChromaOffset =3D MIDPOINT} \end{cases} \end{aligned}\]

15.3.9. Sampler Y=E2=80=99CBCR Conversion

Sampler Y=E2=80=99CBCR conversion performs the fol= lowing operations, which an implementation may combine into a single = mathematical operation:

Sampler Y=E2=80=99= CBCR Range Expansion

Sampler Y=E2=80=99CBCR range expansion is applied = to color channel values after all texel input operations which are not specific to sampler Y=E2=80=99CBCR conversion. For example, the input values to this stage have been converted using the normal format conversion rules.

Sampler Y=E2=80=99CBCR range expansion is not appl= ied if ycbcrModel is VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY. That is, the shader receives the vector C'rgba as output by the = Component Swizzle stage without further modification.

For other values of ycbcrModel, range expansion is applied = to the texel channel values output by the Component Swizzle defined by the components member of VkSamplerYcbcrConversionCreateInfo. Range expansion applies independently to each channel of the image. For the purposes of range expansion and Y=E2=80=99CBCR model conversion, the R and B channels contain color difference (chroma) values and the G channel contains luma. The A channel is not modified by sampler Y=E2=80=99CBCR range expansion.

The range expansion to be applied is defined by the ycbcrRange member of the VkSamplerYcbcrConversionCreateInfo structure:

  • If ycbcrRange is VK_SAMPLER_YCBCR_RANGE_ITU_FULL, the following transformations are applied:

    \[\begin{aligned} Y' &=3D C'_{rgba}[G] \\ C_B &=3D C'_{rgba}[B] - {{2^{(n-1)}}\over{(2^n) - 1}} \\ C_R &=3D C'_{rgba}[R] - {{2^{(n-1)}}\over{(2^n) - 1}} \end{aligned}\]
    Note

    These formulae correspond to the =E2=80=9Cfull range=E2=80=9D encoding i= n the Khronos Data Format Specification.

    Should any future amendments be made to the ITU specifications from whic= h these equations are derived, the formulae used by Vulkan may also be updated to maintain parity.

  • If ycbcrRange is VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, the following transformations are applied:

    \[\begin{aligned} Y' &=3D {{C'_{rgba}[G] \times (2^n-1) - 16\times 2^{n-8}}\over{219\time= s 2^{n-8}}} \\ C_B &=3D {{C'_{rgba}[B] \times \left(2^n-1\right) - 128\times 2^{n-8}}\= over{224\times 2^{n-8}}} \\ C_R &=3D {{C'_{rgba}[R] \times \left(2^n-1\right) - 128\times 2^{n-8}}\= over{224\times 2^{n-8}}} \end{aligned}\]
    Note

    These formulae correspond to the =E2=80=9Cnarrow range=E2=80=9D encoding= in the Khronos Data Format Specification.

  • n is the bit-depth of the channels in the format.

The precision of the operations performed during range expansion must be at least that of the source format.

An implementation may clamp the result= s of these range expansion operations such that Y' falls in the range [0,1], and/or such that CB and C= R fall in the range [-0.5,0.5].

Sampler Y=E2= =80=99CBCR Model Conversion

The range-expanded values are converted between color models, according = to the color model conversion specified in the ycbcrModel member:=

VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY<= /code>

The color channels are not modified by the color model conversion since they are assumed already to represent the desired color model in which the shader is operating; Y=E2=80=99CBCR range expansion i= s also ignored.

VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTIT= Y

The color channels are not modified by the color model conversion and ar= e assumed to be treated as though in Y=E2=80=99CBCR for= m both in memory and in the shader; Y=E2=80=99CBCR range expansion is applied= to the channels as for other Y=E2=80=99CBCR models, with the vector (CR= ,Y',CB,A) provided to the shader.

VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709

The color channels are transformed from a Y=E2=80=99CBCR= representation to an R=E2=80=99G=E2=80=99B' representation as described in the =E2=80=9CBT.709 Y= =E2=80=99CBCR conversion=E2=80=9D section of the Khronos Data Format Specification.

VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601

The color channels are transformed from a Y=E2=80=99CBCR= representation to an R=E2=80=99G=E2=80=99B' representation as described in the =E2=80=9CBT.601 Y= =E2=80=99CBCR conversion=E2=80=9D section of the Khronos Data Format Specification.

VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020

The color channels are transformed from a Y=E2=80=99CBCR= representation to an R=E2=80=99G=E2=80=99B' representation as described in the =E2=80=9CBT.2020 = Y=E2=80=99CBCR conversion=E2=80=9D section of the Khronos Data Format Specification.

In this operation, each output channel is dependent on each input channe= l.

An implementation may clamp the R=E2= =80=99G=E2=80=99B' results of these conversions to the range [0,1].

The precision of the operations performed during model conversion must be at least that of the source format.

The alpha channel is not modified by these model conversions.

Note

Sampling operations in a non-linear color space can introduce color and intensity shifts at sharp transition boundaries. To avoid this issue, the technically precise color correction sequence described in the =E2=80=9CIntroduction to Color Conversions=E2=80=9D chapte= r of the Khronos Data Format Specification may be performed as follows:

The additional calculations and, especially, additional number of sampli= ng operations in the VK_FILTER_LINEAR case can be expected to hav= e a performance impact compared with using the outputs directly; since the variation from =E2=80=9Ccorrect=E2=80=9D results are subtle for most conten= t, the application author should determine whether a more costly implementation is strictly necessary. Note that if chromaFilter and minFilter/mag= Filter are both VK_FILTER_NEAREST, these operations are redundant and sampling= using sampler Y=E2=80=99CBCR con= version at the desired sample coordinates will produce the =E2=80=9Ccorrect=E2=80=9D results witho= ut further processing.

15.4. Texel Output Operations

Texel output instructions are SPIR-V image instructions that wr= ite to an image. Texel output operations are a set of steps that are performed on s= tate, coordinates, and texel values while processing a texel output instruction, and which are common to some or all texel output instructions. They include the following steps, which are performed in the listed order:<= /p>

15.4.1. Texel Output Validation Opera= tions

Texel output validation operations inspect instruction/image st= ate or coordinates, and in certain circumstances cause the write to have no effect= . There are a series of validations that the texel undergoes.

Texel Format Validation

If the image format of the OpTypeImage is not compatible wi= th the VkImageView=E2=80=99s format, the effect of the w= rite on the image view=E2=80=99s memory is undefined, but the write = must not access memory outside of the image view.

15.4.2. Integer Texel Coor= dinate Validation

The integer texel coordinates are validated according to the same rules = as for texel input coordinate validation.

If the texel fails integer texel coordinate validation, then the write h= as no effect.

15.4.3. Sparse Texel Operation=

If the texel attempts to write to an unbound region of a sparse image, t= he texel is a sparse unbound texel. In such a case, if the VkPhysicalDeviceSparseProperties::residencyNonResidentStrict property is VK_TRUE, the sparse unbound texel write has no eff= ect. If residencyNonResidentStrict is VK_FALSE, the wr= ite may have a side effect that becomes visible to other accesses to unbound texels in any resource, but will not be visible to any device memory allocated by the application.

15.4.4. Texel Output Format Co= nversion

If the image format is sRGB, a linear to sRGB conversion is applied to t= he R, G, and B components as described in the =E2=80=9CsRGB EOTF=E2=80=9D sect= ion of the Khronos Data Format Specification. The A component, if present, is unchanged.

Texels then undergo a format conversion from the floating point, signed,= or unsigned integer type of the texel data to the VkFormat of th= e image view. Any unused components are ignored.

Each component is converted based on its type and size (as defined in th= e Format Definition section for each VkFormat). Floating-point outputs are converted as described in Floating-Point Format Conversions and Fixed-Point Data Conversion. Integer outputs are converted such that their value is preserved. The converted value of any integer that cannot be represented in the target format is undefined.

15.5. Derivative Operations

SPIR-V derivative instructions include OpDPdx, OpDPdy= , OpDPdxFine, OpDPdyFine, OpDPdxCoarse= , and OpDPdyCoarse. Derivative instructions are only available in a fragment shader.

3D"vulkantexture2"
Figure 11. Implicit Derivatives

Derivatives are computed as if there is a 2=C3=972 neighborhood of fragments for each fragment shader invocation. These neighboring fragments are used to compute derivatives with the assumption that the values of P in the neighborhood are piecewise linear. It is further assumed that the values of P in the neighborhood are locally continuous, therefore derivatives in non-uniform control flow are undefined= .

\[\begin{aligned} dPdx_{i_1,j_0} & =3D dPdx_{i_0,j_0} & =3D P_{i_1,j_0} - P_{i_0,j_0}= \\ dPdx_{i_1,j_1} & =3D dPdx_{i_0,j_1} & =3D P_{i_1,j_1} - P_{i_0,j_1}= \\ \\ dPdy_{i_0,j_1} & =3D dPdy_{i_0,j_0} & =3D P_{i_0,j_1} - P_{i_0,j_0}= \\ dPdy_{i_1,j_1} & =3D dPdy_{i_1,j_0} & =3D P_{i_1,j_1} - P_{i_1,j_0} \end{aligned}\]

The Fine derivative instructions m= ust return the values above, for a group of fragments in a 2=C3=972 neighborhood. Coarse derivatives may return only two va= lues. In this case, the values should be:

\[\begin{aligned} dPdx & =3D \begin{cases} dPdx_{i_0,j_0} & \text{preferred}\\ dPdx_{i_0,j_1} \end{cases} \\ dPdy & =3D \begin{cases} dPdy_{i_0,j_0} & \text{preferred}\\ dPdy_{i_1,j_0} \end{cases} \end{aligned}\]

OpDPdx and OpDPdy mus= t return the same result as either OpDPdxFine or OpDPdxCoarse and either OpDPd= yFine or OpDPdyCoarse, respectively. Implementations must make the same choice= of either coarse or fine for both OpDPdx and OpDPdy, and implementations should make the choice that is more efficient to compute.

For multi-planar formats, the derivatives are computed based on the plan= e with the largest dimensions.

15.6. Normalized Texel Coordinate= Operations

If the image sampler instruction provides normalized texel coordinates, = some of the following operations are performed.

15.6.1. Projection Operation

For Proj image operations, the normalized texel coordinates (s,t,r,q,a) and (if present) the Dref coordinate are transformed as follows:

\[\begin{aligned} s & =3D \frac{s}{q}, & \text{for 1D, 2D, or 3D image} \= \ \\ t & =3D \frac{t}{q}, & \text{for 2D or 3D image} \\ \\ r & =3D \frac{r}{q}, & \text{for 3D image} \\ \\ D_{\textit{ref}} & =3D \frac{D_{\textit{ref}}}{q}, & \text{if provi= ded} \end{aligned}\]

15.6.2. Derivative Image Op= erations

Derivatives are used for LOD selection. These derivatives are either implicit (in an ImplicitLod image instruction in a fragment shader) or explicit (provided explicitly by shade= r to the image instruction in any shader).

For implicit derivatives image instructions, the derivatives of texel coordinates are calculated in the same manner as derivative operations above. That is:

\[\begin{aligned} \partial{s}/\partial{x} & =3D dPdx(s), & \partial{s}/\partial{y} &a= mp; =3D dPdy(s), & \text{for 1D, 2D, Cube, or 3D image} \\ \partial{t}/\partial{x} & =3D dPdx(t), & \partial{t}/\partial{y} &a= mp; =3D dPdy(t), & \text{for 2D, Cube, or 3D image} \\ \partial{u}/\partial{x} & =3D dPdx(u), & \partial{u}/\partial{y} &a= mp; =3D dPdy(u), & \text{for Cube or 3D image} \end{aligned}\]

Partial derivatives not defined above for certain image dimensionalities= are set to zero.

For explicit LOD image instructions, if the opt= ional SPIR-V operand Grad is provided, then the operand values are use= d for the derivatives. The number of components present in each derivative for a given image dimensionality matches the number of partial derivatives computed above.

If the optional SPIR-V operand Lod is provided, then derivatives are set to zero, the cube map derivative transformation is skipped, and the scale factor operation is skipped. Instead, the floating point scalar coordinate is directly assigned to =CE=BBbase as described in Level-of-Detail Operation.

For implicit derivative image instructions, the partial derivative value= s may be computed by linear approximation u= sing a 2=C3=972 neighborhood of shader invocations (known as a quad), as described above. If the instruction is in control flow that is not uniform across the quad, then the derivative values and hence the implicit LOD values are undefined.=

If the image or sampler object used by an implicit derivative image instruction is not uniform across the quad and quadDivergentImplicitLod is not supported, then the derivative and LOD values are undefined. Implicit derivatives are well-defined when the image and sampler and contro= l flow are uniform across the quad, even if they diverge between different quads.

If quadDivergentImplicitLod is supported, then derivatives and implicit LOD values are well-defined eve= n if the image or sampler object are not uniform within a quad. The derivatives are computed as specified above, and the implicit LOD calculation proceeds for each shader invocation using its respective image and sampler object.

For the purposes of implicit derivatives, Flat fragment inp= ut variables are uniform within a quad.

15.6.3. Cube Map Fa= ce Selection and Transformations

For cube map image instructions, the (s,t,r) c= oordinates are treated as a direction vector (rx,ry,rz). The direction vector is used to select a cube map face. The direction vector is transformed to a per-face texel coordinate system (sface,tface), The directio= n vector is also used to transform the derivatives to per-face derivatives.

15.6.4. Cube Map Face Selection

The direction vector selects one of the cube map=E2=80=99s faces based o= n the largest magnitude coordinate direction (the major axis direction). Since two or more coordinates can have id= entical magnitude, the implementation must have rules to disambi= guate this situation.

The rules should have as the first rul= e that rz wins over ry and rx, and the second rule that ry = wins over rx. An implementation may choose other rules,= but the rules must be deterministic and depend only on (rx,ry<= /sub>,rz).

The layer number (corresponding to a cube map face), the coordinate selections for sc, = tc, rc, and the sele= ction of derivatives, are determined by the major axis direction as specified in the following two tables.

Table 25. Cube map face and coordinate selection
Major Axis Direction Layer Number Cube Map Face sc<= /sub> tc<= /sub> rc<= /sub>

+rx

0

Pos= itive X

-rz

-ry

rx

-rx

1

Neg= ative X

+rz

-ry

rx

+ry

2

Pos= itive Y

+rx

+rz

ry

-ry

3

Neg= ative Y

+rx

-rz

ry

+rz

4

Pos= itive Z

+rx

-ry

rz

-rz

5

Neg= ative Z

-rx

-ry

rz

Table 26. Cube map derivative selection
Major Axis Direction =E2=88= =82sc / =E2=88=82x =E2=88= =82sc / =E2=88=82y =E2=88= =82tc / =E2=88=82x =E2=88= =82tc / =E2=88=82y =E2=88= =82rc / =E2=88=82x =E2=88= =82rc / =E2=88=82y

+rx

-=E2=88=82rz / =E2=88=82x

-=E2=88=82rz / =E2=88=82y

-=E2=88=82ry / =E2=88=82x

-=E2=88=82ry / =E2=88=82y

+=E2=88=82rx / =E2=88=82x

+=E2=88=82rx / =E2=88=82y

-rx

+=E2=88=82rz / =E2=88=82x

+=E2=88=82rz / =E2=88=82y

-=E2=88=82ry / =E2=88=82x

-=E2=88=82ry / =E2=88=82y

-=E2=88=82rx / =E2=88=82x

-=E2=88=82rx / =E2=88=82y

+ry

+=E2=88=82rx / =E2=88=82x

+=E2=88=82rx / =E2=88=82y

+=E2=88=82rz / =E2=88=82x

+=E2=88=82rz / =E2=88=82y

+=E2=88=82ry / =E2=88=82x

+=E2=88=82ry / =E2=88=82y

-ry

+=E2=88=82rx / =E2=88=82x

+=E2=88=82rx / =E2=88=82y

-=E2=88=82rz / =E2=88=82x

-=E2=88=82rz / =E2=88=82y

-=E2=88=82ry / =E2=88=82x

-=E2=88=82ry / =E2=88=82y

+rz

+=E2=88=82rx / =E2=88=82x

+=E2=88=82rx / =E2=88=82y

-=E2=88=82ry / =E2=88=82x

-=E2=88=82ry / =E2=88=82y

+=E2=88=82rz / =E2=88=82x

+=E2=88=82rz / =E2=88=82y

-rz

-=E2=88=82rx / =E2=88=82x

-=E2=88=82rx / =E2=88=82y

-=E2=88=82ry / =E2=88=82x

-=E2=88=82ry / =E2=88=82y

-=E2=88=82rz / =E2=88=82x

-=E2=88=82rz / =E2=88=82y

15.6.5. Cube Map Coordinate = Transformation

\[\begin{aligned} s_{\textit{face}} & =3D \frac{1}{2} \times \frac{s_c}{|r_c|} + \frac{1}{2} \\ t_{\textit{face}} & =3D \frac{1}{2} \times \frac{t_c}{|r_c|} + \frac{1}{2} \\ \end{aligned}\]

15.6.6. Cube Map Derivative = Transformation

\[\begin{aligned} \frac{\partial{s_{\textit{face}}}}{\partial{x}} &=3D \frac{\partial}{\partial{x}} \left ( \frac{1}{2} \times \frac{s_{c}}{|r= _{c}|} + \frac{1}{2}\right ) \\ \frac{\partial{s_{\textit{face}}}}{\partial{x}} &=3D \frac{1}{2} \times \frac{\partial}{\partial{x}} \left ( \frac{s_{c}}{|r_{c}|} \right ) \\ \frac{\partial{s_{\textit{face}}}}{\partial{x}} &=3D \frac{1}{2} \times \left ( \frac{ |r_{c}| \times \partial{s_c}/\partial{x} -s_c \times {\partial{r_{c}}}/{\partial{x}}} {\left ( r_{c} \right )^2} \right ) \end{aligned}\]
\[\begin{aligned} \frac{\partial{s_{\textit{face}}}}{\partial{y}} &=3D \frac{1}{2} \times \left ( \frac{ |r_{c}| \times \partial{s_c}/\partial{y} -s_c \times {\partial{r_{c}}}/{\partial{y}}} {\left ( r_{c} \right )^2} \right )\\ \frac{\partial{t_{\textit{face}}}}{\partial{x}} &=3D \frac{1}{2} \times \left ( \frac{ |r_{c}| \times \partial{t_c}/\partial{x} -t_c \times {\partial{r_{c}}}/{\partial{x}}} {\left ( r_{c} \right )^2} \right ) \\ \frac{\partial{t_{\textit{face}}}}{\partial{y}} &=3D \frac{1}{2} \times \left ( \frac{ |r_{c}| \times \partial{t_c}/\partial{y} -t_c \times {\partial{r_{c}}}/{\partial{y}}} {\left ( r_{c} \right )^2} \right ) \end{aligned}\]
editing-note

(Bill) Note that we never revisited ARB_texture_cubemap after we introdu= ced dependent texture fetches (ARB_fragment_program and ARB_fragment_shader).

The derivatives of sface and tface are only valid for non-dependent texture fetches (pre OpenGL 2.0).

15.6.7. Scale Factor Operation, Level-of-Detail Operation and= Image Level(s) Selection

LOD selection can be either explicit (= provided explicitly by the image instruction) or implicit (determined from a scale factor calculated from th= e derivatives). The implicit LOD selected can be queried = using the SPIR-V instruction OpImageQueryLod, which gives access to the = =CE=BB' and dl values, defined below.

Scale Factor Operation

The magnitude of the derivatives are calculated by:

mux =3D |=E2=88=82s/=E2=88=82x| =C3=97 wbase

mvx =3D |=E2=88=82t/=E2=88=82x| =C3=97 hbase

mwx =3D |=E2=88=82r/=E2=88=82x| =C3=97 dbase

muy =3D |=E2=88=82s/=E2=88=82y| =C3=97 wbase

mvy =3D |=E2=88=82t/=E2=88=82y| =C3=97 hbase

mwy =3D |=E2=88=82r/=E2=88=82y| =C3=97 dbase

where:

=E2=88=82t/=E2=88=82x =3D =E2=88=82t/=E2=88=82y =3D 0= (for 1D images)

=E2=88=82r/=E2=88=82x =3D =E2=88=82r/=E2=88=82y =3D 0= (for 1D, 2D or Cube images)

and

wbase =3D image.w

hbase =3D image.h

dbase =3D image.d

(for the baseMipLevel, from the image descriptor).

A point sampled in screen space has an elliptical footprint in texture space. The minimum and maximum scale factors (=CF=81min, =CF=81max) should be the minor and major axes of this ellipse.

The scale factors =CF=81x = and =CF=81y, calculated from the magnitude of the derivatives in x and y, are used to compute the minimum an= d maximum scale factors.

=CF=81x and =CF= =81y may be approximate= d with functions fx and fy, subject to the following constraints:

\[\begin{aligned} & f_x \text{\ is\ continuous\ and\ monotonically\ increasing\ in\ each\= of\ } m_{ux}, m_{vx}, \text{\ and\ } m_{wx} \\ & f_y \text{\ is\ continuous\ and\ monotonically\ increasing\ in\ each\= of\ } m_{uy}, m_{vy}, \text{\ and\ } m_{wy} \end{aligned}\]
\[\begin{aligned} \max(|m_{ux}|, |m_{vx}|, |m_{wx}|) \leq f_{x} \leq \sqrt{2} (|m_{ux}| + |m_{vx}| + |m_{wx}|) \\ \max(|m_{uy}|, |m_{vy}|, |m_{wy}|) \leq f_{y} \leq \sqrt{2} (|m_{uy}| + |m_{vy}| + |m_{wy}|) \end{aligned}\]
editing-note

(Bill) For reviewers only - anticipating questions.

We only support implicit derivatives for normalized texel coordinates.

So we are documenting the derivatives in s,t,r (normalized texel coordinates) rather than u,v,w (unnormalized texel coordinates) as in OpenG= L and OpenGL ES specifications. (I know, u,v,w is the way it has been documented since OpenGL V1.0.)

Also there is no reason to have conditional application of wbase, hbase, dbase for rectangle textures either, si= nce they do not support implicit derivatives.

The minimum and maximum scale factors (=CF=81min= ,=CF=81max) are determined by:

=CF=81max =3D max(=CF=81x, =CF= =81y)

=CF=81min =3D min(=CF=81x, =CF= =81y)

The ratio of anisotropy is determined by:

=CE=B7 =3D min(=CF=81max/=CF=81min, maxAniso)

where:

sampler.maxAniso =3D maxAnisotropy (from sampler descriptor)

limits.maxAniso =3D maxSamplerAnisot= ropy (from physical device limits)

maxAniso =3D min(sampler.maxAniso, limits.maxAniso)

If =CF=81max =3D =CF=81min =3D = 0, then all the partial derivatives are zero, the fragment=E2=80=99s footprint in texel space is a point, and N should be treated as 1. If =CF=81max =E2=89=A0 0 and =CF=81min =3D 0 then all partial derivatives along one axis are zero, the fragment=E2=80=99s footprint in te= xel space is a line segment, and =CE=B7 should be treated as maxAniso<= /span>. However, anytime the footprint is small in texel space the implementation may use a smaller value of =CE=B7, even when =CF=81min is zero or close to zero. If either VkPhysicalDeviceFeatures::sam= plerAnisotropy or VkSamplerCreateInfo::anisotropyEnable= are VK_FALSE, maxAniso is set to 1.

If =CE=B7 =3D 1, sampling is isotropic. If =CE=B7 > 1, sampling is anisotropic.

The sampling rate (N) is derived as:

N =3D =E2=8C=88=CE=B7=E2=8C=89

An implementation may round N up to the nearest supported sampling rate. An implementation may use the value of N as an approximation of =CE=B7.

Level-of-Detail Operation

The LOD parameter =CE=BB is computed as follow= s:

\[\begin{aligned} \lambda_{base}(x,y) & =3D \begin{cases} shaderOp.Lod & \text{(from optio= nal SPIR-V operand)} \\ \log_2 \left ( \frac{\rho_{max}}{\eta} \right ) & \text{otherwise} \end{cases} \\ \lambda'(x,y) & =3D \lambda_{base} + \mathbin{clamp}(sampler.bias= + shaderOp.bias,-maxSamplerLodBias,maxSamplerLodBias) \\ \lambda & =3D \begin{cases} lod_{max}, & \lambda' > lod_{max} \\ \lambda', & lod_{min} \leq \lambda' \leq lod_{max} \\ lod_{min}, & \lambda' < lod_{min} \\ \textit{undefined}, & lod_{min} > lod_{max} \end{cases} \end{aligned}\]

where:

\[\begin{aligned} sampler.bias & =3D mipLodBias & \text{(from sampler descripto= r)} \\ shaderOp.bias & =3D \begin{cases} Bias & \text{(from optional SPIR-V operand)} \\ 0 & \text{otherwise} \end{cases} \\ sampler.lod_{min} & =3D minLod & \text{(from sampler descriptor)} = \\ shaderOp.lod_{min} & =3D \begin{cases} MinLod & \text{(from optional SPIR-V operand)} \\ 0 & \text{otherwise} \end{cases} \\ \\ lod_{min} & =3D \max(sampler.lod_{min}, shaderOp.lod_{min}) \\ lod_{max} & =3D maxLod & \text{(from sampler descriptor)} \end{aligned}\]

and maxSamplerLodBias is the value of the VkPhysicalDeviceLimits feature maxSamplerLodBias.

15.6.8. (s,t,r,q,a) to (u,v,= w,a) Transformation

The normalized texel coordinates are scaled by the image level dimension= s and the array layer is selected. This transformation is performed once for each level (d<= /span> or dhi and dlo) used in filtering.

\[\begin{aligned} u(x,y) & =3D s(x,y) \times width_{level} \\ v(x,y) & =3D \begin{cases} 0 & \text{for 1D images} \\ t(x,y) \times height_{level} & \text{otherwise} \end{cases} \\ w(x,y) & =3D \begin{cases} 0 & \text{for 2D or Cube images} \\ r(x,y) \times depth_{level} & \text{otherwise} \end{cases} \\ \\ a(x,y) & =3D \begin{cases} a(x,y) & \text{for array images} \\ 0 & \text{otherwise} \end{cases} \end{aligned}\]

Operations then proceed to Unnormalized Texel Coordinate Operations.

15.7. Unnormalized Tex= el Coordinate Operations

15.7.1. (u,v,w,a) to (i,j,k,l,n= ) Transformation And Array Layer Selection

The unnormalized texel coordinates are transformed to integer texel coordinates relative to the selected mipmap level.

The layer index l is computed as:

l =3D clamp(RNE(a), 0, layerCount - 1) += =20 baseArrayLayer

where layerCount is the number of layers in the image subre= source range of the image view, baseArrayLayer is the first layer fro= m the subresource range, and where:

\[\begin{aligned} \mathbin{RNE}(a) & =3D \begin{cases} \mathbin{roundTiesToEven}(a) & \text{preferred, fr= om IEEE Std 754-2008 Floating-Point Arithmetic} \\ \left \lfloor a + 0.5 \right \rfloor & \text{alternative} \end{cases} \end{aligned}\]

The sample index n is assigned the value zero.

Nearest filtering (VK_FILTER_NEAREST) computes the integer = texel coordinates that the unnormalized coordinates lie within:

\[\begin{aligned} i &=3D \lfloor u \rfloor \\ j &=3D \lfloor v \rfloor \\ k &=3D \lfloor w \rfloor \end{aligned}\]

Linear filtering (VK_FILTER_LINEAR) computes a set of neigh= boring coordinates which bound the unnormalized coordinates. The integer texel coordinates are combinations of i= 0 or i1, j0 or j1= , k0 or k1, as well as weights =CE=B1, =CE=B2, and =CE=B3.

\[\begin{aligned} i_0 &=3D \lfloor u - 0.5 \rfloor \\ i_1 &=3D i_0 + 1 \\ j_0 &=3D \lfloor v - 0.5 \rfloor \\ j_1 &=3D j_0 + 1 \\ k_0 &=3D \lfloor w - 0.5 \rfloor \\ k_1 &=3D k_0 + 1 \\ \alpha &=3D \left(u - 0.5\right) - i_0 \\ \beta &=3D \left(v - 0.5\right) - j_0 \\ \gamma &=3D \left(w - 0.5\right) - k_0 \end{aligned}\]

Cubic filtering (VK_FILTER_CUBIC_IMG) computes a set of nei= ghboring coordinates which bound the unnormalized coordinates. The integer texel coordinates are combinations of i= 0, i1, i2 or i3= , j0, j= 1, j2 or j3, as well as weights =CE=B1 and = =CE=B2.

\[\begin{aligned} i_{0} & =3D \left \lfloor u - \frac{3}{2} \right \rfloor & i_{1} &= amp; =3D i_{0} + 1 & i_{2} & =3D i_{1} + 1 & i_{3} & =3D i_= {2} + 1 \\[1em] j_{0} & =3D \left \lfloor v - \frac{3}{2} \right \rfloor & j_{1} &= amp; =3D j_{0} + 1 & j_{2} & =3D j_{1} + 1 & j_{3} & =3D j_= {2} + 1 \\ \\ \alpha & =3D \mathbin{frac} \left ( u - \frac{1}{2} \right ) \\[1em] \beta & =3D \mathbin{frac} \left ( v - \frac{1}{2} \right ) \end{aligned}\]

If the image instruction includes a ConstOffset operand, the constant offsets (=CE=94i, =CE=94j, =CE=94<= sub>k) are added to (i,j,k) components of the integer texel coordi= nates.

15.8. Integer Texel Coord= inate Operations

Integer texel coordinate operations may supply a LOD which texels are to be read from or written to using the optional SPIR-V operand Lod. If the Lod is provided then it must be an integer.

The image level selected is:

\[\begin{aligned} d & =3D level_{base} + \begin{cases} Lod & \text{(from optional SPIR-V operand)} \\ 0 & \text{otherwise} \end{cases} \\ \end{aligned}\]

If d does not lie in the range [baseMipLevel, baseMipLevel + levelCount) then any value= s fetched are undefined, and any writes are discarded.

15.9. Image Sample Operations

15.9.1. Wrapping Operation

Cube images ignore the wrap modes specified in the sampler. Instead, if VK_FILTER_NEAREST is used within a mip level then VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE is used, and if VK_FILTER_LINEAR is used within a mip level then sampling at t= he edges is performed as described earlier in the Cube map edge handling section.

The first integer texel coordinate i is transformed based on the addressModeU parameter of the sampler.

\[\begin{aligned} i &=3D \begin{cases} i \bmod size & \text{for repeat} \\ (size - 1) - \mathbin{mirror} ((i \bmod (2 \times size)) - size) & \text{for mirrored re= peat} \\ \mathbin{clamp}(i,0,size-1) & \text{for clamp to e= dge} \\ \mathbin{clamp}(i,-1,size) & \text{for clamp to b= order} \\ \mathbin{clamp}(\mathbin{mirror}(i),0,size-1) & \text{for mirror cl= amp to edge} \end{cases} \end{aligned}\]

where:

\[\begin{aligned} & \mathbin{mirror}(n) =3D \begin{cases} n & \text{for}\ n \geq 0 \\ -(1+n) & \text{otherwise} \end{cases} \end{aligned}\]

j (for 2D and Cube image) and k (for 3D image) are similarly transformed based on the addressModeV and addressModeW parameters of the sampler, respectively.

15.9.2. Texel Gathering

SPIR-V instructions with Gather in the name return a vector= derived from a 2=C3=972 rectangular region of texels in the base level of the image view. The rules for the VK_FILTER_LINEAR minification filter are app= lied to identify the four selected texels. Each texel is then converted to an RGBA value according to conversion to RGBA and then swizzled. A four-component vector is then assembled by taking the component indicated by the Component value in the instruction from the swizzled co= lor value of the four texels:

\[\begin{aligned} \tau[R] &=3D \tau_{i0j1}[level_{base}][comp] \\ \tau[G] &=3D \tau_{i1j1}[level_{base}][comp] \\ \tau[B] &=3D \tau_{i1j0}[level_{base}][comp] \\ \tau[A] &=3D \tau_{i0j0}[level_{base}][comp] \end{aligned}\]

where:

\[\begin{aligned} \tau[level_{base}][comp] &=3D \begin{cases} \tau[level_{base}][R], & \text{for}\ comp =3D 0 \\ \tau[level_{base}][G], & \text{for}\ comp =3D 1 \\ \tau[level_{base}][B], & \text{for}\ comp =3D 2 \\ \tau[level_{base}][A], & \text{for}\ comp =3D 3 \end{cases}\\ comp & \,\text{from SPIR-V operand Component} \end{aligned}\]

OpImage*Gather must not b= e used on a sampled image with sampler Y=E2=80=99CBCR con= version enabled.

15.9.3. Texel Filtering

If =CE=BB is less than or equal to zero, the t= exture is said to be magnified, and the filter mode within a mip level is selected by t= he magFilter in the sampler. If =CE=BB is greater than zero, the texture is sa= id to be minified, and the filter mode within a mip level is selected by th= e minFilter in the sampler.

Within a mip level, VK_FILTER_NEAREST filtering selects a s= ingle value using the (i, j, k) texel coordinates, with all t= exels taken from layer l.

\[\begin{aligned} \tau[level] &=3D \begin{cases} \tau_{ijk}[level], & \text{for 3D image} \\ \tau_{ij}[level], & \text{for 2D or Cube image} \\ \tau_{i}[level], & \text{for 1D image} \end{cases} \end{aligned}\]

Within a mip level, VK_FILTER_LINEAR filtering combines 8 (= for 3D), 4 (for 2D or Cube), or 2 (for 1D) texel values, using the weights computed earlier:

\[\begin{aligned} \tau_{3D}[level] & =3D reduce((1-\alpha)(1-\beta)(1-\gamma),\tau_{i0j0k= 0}[level], \\ & \, (\alpha)(1-\beta)(1-\gamma),\tau_{i1j0k0}[l= evel], \\ & \, (1-\alpha)(\beta)(1-\gamma),\tau_{i0j1k0}[l= evel], \\ & \, (\alpha)(\beta)(1-\gamma),\tau_{i1j1k0}[lev= el], \\ & \, (1-\alpha)(1-\beta)(\gamma),\tau_{i0j0k1}[l= evel], \\ & \, (\alpha)(1-\beta)(\gamma),\tau_{i1j0k1}[lev= el], \\ & \, (1-\alpha)(\beta)(\gamma),\tau_{i0j1k1}[lev= el], \\ & \, (\alpha)(\beta)(\gamma),\tau_{i1j1k1}[level= ]) \end{aligned}\]
\[\begin{aligned} \tau_{2D}[level] & =3D reduce((1-\alpha)(1-\beta),\tau_{i0j0}[level], \= \ & \, (\alpha)(1-\beta),\tau_{i1j0}[level], \\ & \, (1-\alpha)(\beta),\tau_{i0j1}[level], \\ & \, (\alpha)(\beta),\tau_{i1j1}[level]) \end{aligned}\]
\[\begin{aligned} \tau_{1D}[level] & =3D reduce((1-\alpha),\tau_{i0}[level], \\ & \, (\alpha),\tau_{i1}[level]) \end{aligned}\]
\[\begin{aligned} \tau[level] &=3D \begin{cases} \tau_{3D}[level], & \text{for 3D image} \\ \tau_{2D}[level], & \text{for 2D or Cube image} \\ \tau_{1D}[level], & \text{for 1D image} \end{cases} \end{aligned}\]

The function reduce() is defined to operate on= pairs of weights and texel values as follows. When using linear or anisotropic filtering, the values of multiple texels are combined using a weighted average to produce a filtered texture value. However, a filtered texture value can als= o be produced by computing per-component minimum and maximum values over the set of texels that would normally be averaged. The VkSamplerReductionModeCreateInfoEX= T::reductionMode controls the process by which multiple texels are combined to produce a filtered texture value. When set to VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, a = weighted average is computed. If the reduction mode is VK_SAMPLER_REDUCTION_MODE_MIN_EXT or VK_SAMPLER_REDUCTION_MODE_MAX_EXT, reduce()= computes a component-wise minimum or maximum, respectively, of the components of the set of provided texels with non-zero weights.

Within a mip level, VK_FILTER_CUBIC_IMG filtering computes = a weighted average of 16 (for 2D), or 4 (for 1D) texel values, using the weights computed during texel selection.

Catmull-Rom Spine interpolation of four points is defined by the equatio= n:

\[\begin{aligned} cinterp(\tau_0, \tau_1, \tau_2, \tau_3, \omega) =3D \frac{1}{2} \begin{bmatrix}1 & \omega & \omega^2 & \omega^3 \end{bmatrix} \times \begin{bmatrix} 0 & 2 & 0 & 0 \\ -1 & 0 & 1 & 0 \\ 2 & -5 & 4 & 1 \\ -1 & 3 & -3 & 1 \end{bmatrix} \times \begin{bmatrix} \tau_0 \\ \tau_1 \\ \tau_2 \\ \tau_3 \end{bmatrix} \end{aligned}\]

Using the values calculated in texel selection, this equation is applied= to the four points in 1D images. For 2D images, the this equation is evaluated first for each row, and the result is then fed back into the equation and interpolated again:

=CF=841D[level] =3D cinterp(=CF=84i0<= /sub>[level], =CF=84i1[level], =CF=84i2[level], =CF=84i3[level], =CE=B1)

=CF=84j0[level] =3D cinterp(=CF=84i0j= 0[level], =CF=84i1j0[level], =CF=84i2j0[level], =CF=84i3j0[level], =CE=B1)<= /p>

=CF=84j1[level] =3D cinterp(=CF=84i0j= 1[level], =CF=84i1j1[level], =CF=84i2j1[level], =CF=84i3j1[level], =CE=B1)<= /p>

=CF=84j2[level] =3D cinterp(=CF=84i0j= 2[level], =CF=84i1j2[level], =CF=84i2j2[level], =CF=84i3j2[level], =CE=B1)<= /p>

=CF=84j3[level] =3D cinterp(=CF=84i0j= 3[level], =CF=84i1j3[level], =CF=84i2j3[level], =CF=84i3j3[level], =CE=B1)<= /p>

=CF=842D[level] =3D cinterp(=CF=84j0<= /sub>[level], =CF=84j1[level], =CF=84j2[level], =CF=84j3[level], =CE=B2)

\[\begin{aligned} \tau[level] &=3D \begin{cases} \tau_{2D}[level], & \text{for 2D image} \\ \tau_{1D}[level], & \text{for 1D image} \end{cases} \end{aligned}\]

Finally, mipmap filtering either selects a value from one mip level or computes a weighted average between neighboring mip levels:

\[\begin{aligned} \tau &=3D \begin{cases} \tau[d], & \text{for mip mode BASE or NEAREST} \\ reduce((1-\delta),\tau[d_{hi}],\delta,\tau[d_{lo}]), & \text{for mi= p mode LINEAR} \end{cases} \end{aligned}\]

15.9.4. Texel Anisotropic F= iltering

Anisotropic filtering is enabled by the anisotropyEnable in= the sampler. When enabled, the image filtering scheme accounts for a degree of anisotropy.

The particular scheme for anisotropic texture filtering is implementatio= n dependent. Implementations should consider the magFilter, minFilter and mipmapMode of the sampler to control the specifics of the anis= otropic filtering scheme used. In addition, implementations should consi= der minLod and maxLod of the sampler.

The following describes one particular approach to implementing anisotro= pic filtering for the 2D Image case, implementations m= ay choose other methods:

Given a magFilter, minFilter of VK_FILTE= R_LINEAR and a mipmapMode of VK_SAMPLER_MIPMAP_MODE_NEAREST:

Instead of a single isotropic sample, N isotropic samples are be sampled within the image footprint of the image level d t= o approximate an anisotropic filter. The sum =CF=842Daniso is defined using= the single isotropic =CF=842D(u,v) at level d.

\[\begin{aligned} \tau_{2Daniso} & =3D \frac{1}{N}\sum_{i=3D1}^{N} {\tau_{2D}\left ( u \left ( x - \frac{1}{2} + \frac{i}{N+1} , y \right ), \left ( v \left (x-\frac{1}{2}+\frac{i}{N+1} \right ), y \right ) \right )}, & \text{when}\ \rho_{x} > \rho_{y} \\ \tau_{2Daniso} &=3D \frac{1}{N}\sum_{i=3D1}^{N} {\tau_{2D}\left ( u \left ( x, y - \frac{1}{2} + \frac{i}{N+1} \right ), \left ( v \left (x,y-\frac{1}{2}+\frac{i}{N+1} \right ) \right ) \right )}, & \text{when}\ \rho_{y} \geq \rho_{x} \end{aligned}\]

When VkSamplerReductionModeCreateIn= foEXT::reductionMode is set to VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, the above s= ummation is used. If the reduction mode is VK_SAMPLER_REDUCTION_MODE_MIN_EXT or VK_SAMPLER_REDUCTION_MODE_MAX_EXT, then the value is instead c= omputed as \tau_{2Daniso} =3D reduce(\tau_1, =E2=80=A6=E2=80=8B,= \tau_N), combining all texel values with non-zero weights.

15.10. Image Operation Steps

Each step described in this chapter is performed by a subset of the imag= e instructions:

  • Texel Input Validation Operations, Format Conversion, Texel Replacement, Conversion to RGBA, and Component Swizzle: Performed by all instructions except OpImageWrite.

  • Depth Comparison: Performed by OpImage*Dref in= structions.

  • All Texel output operations: Performed by OpImageWrite.

  • Projection: Performed by all OpImage*Proj inst= ructions.

  • Derivative Image Operations, Cube Map Operations, Scale Factor Operation, Level-of-Detail Operation and Image Level(s) Selection, and Texel Anisotropic Filtering: Performed by all OpImageSample* a= nd OpImageSparseSample* instructions.

  • (s,t,r,q,a) to (u,v,w,a) Transformation, Wrapping, and (u,v,w,a) to (i,j,k,l,n) Transformation And Array Layer Selection: Performed by all OpImageSample, OpImageSparseSample, and OpImage*Gather instructions.

  • Texel Gathering: Performed by OpImage*Gather i= nstructions.

  • Texel Filtering: Performed by all OpImageSample* and OpImageSparseSample* instructions.

  • Sparse Residency: Performed by all OpImageSparse* instructi= ons.

16. Queries

Queries provide a mechanism to return information about the pro= cessing of a sequence of Vulkan commands. Query operations are asynchronous, and as such, their results are not returned immediately. Instead, their results, and their availability status, are stored in a Query Pool. The state of these queries can be read ba= ck on the host, or copied to a buffer object on the device.

The supported query types are Occlusion Queries, Pipeline Statistics Queries, and Timestamp Queries.

16.1. Query Pools

Queries are managed using query pool objects. Each query pool is a collection of a specific number of queries of a particular type.

Query pools are represented by VkQueryPool handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkQueryPool)

To create a query pool, call:

VkResult vkCreateQ=
ueryPool(
    VkDevice                                    device,
    const VkQueryPoolCreateInfo*          =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkQueryPool*                                pQueryPool);
  • device is the logical device that creates the query pool.

  • pCreateInfo is a pointer to an instance of the VkQueryPoolCreateInfo structure containing the number and type= of queries to be managed by the pool.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pQueryPool is a pointer to a VkQueryPool h= andle in which the resulting query pool object is returned.

Valid Usage (Implicit)
  • device must be a valid VkDevice = handle

  • pCreat= eInfo must be a valid pointer to a= valid VkQueryPoolCreateInfo structure

  • If pAll= ocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocatio= nCallbacks structure

  • pQueryP= ool must be a valid pointer to a <= code>VkQueryPool handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkQueryPoolCreateInfo structure is defined as:

typedef struct VkQueryPoolCreat=
eInfo {
    VkStructureType                  sType;
    const void*                      pNext;
    VkQueryPoolCreateFlags           flags;
    VkQueryType                      queryType;
    uint32_t                         queryCount;
    VkQueryPipelineStatisticFlags    pipelineStatistics;
} VkQueryPoolCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • queryType is a VkQueryType value specifyin= g the type of queries managed by the pool.

  • queryCount is the number of queries managed by the pool.

  • pipelineStatistics is a bitmask of VkQueryPipelineStatisticFlagBits spec= ifying which counters will be returned in queries on the new pool, as described below in Pipeline Statistics Queries.

pipelineStatistics is ignored if queryType is = not VK_QUERY_TYPE_PIPELINE_STATISTICS.

Valid Usage
Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_QUERY_PO= OL_CREATE_INFO

  • pNext= must be NULL

  • flags<= /code> must be 0

  • quer= yType must be a valid VkQueryType value

typedef VkFlags VkQueryPoolCreateFlags;

VkQueryPoolCreateFlags is a bitmask type for setting a mask= , but is currently reserved for future use.

To destroy a query pool, call:

void vkDestroyQueryPool(
    VkDevice                                    device,
    VkQueryPool                                 queryPool,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the query pool.<= /p>

  • queryPool is the query pool to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to queryPool must have completed execution

  • If VkAllocationCallbacks were provided when queryPool was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when queryPool= was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice= handle

  • If quer= yPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle

  • If pAl= locator is not NULL, pAllocator must be a valid pointer to a valid VkAllocati= onCallbacks structure

  • If queryPo= ol is a valid handle, it must have= been created, allocated, or retrieved from device

Host Synchronization
  • Host access to queryPool must be externally synchronized

Possible values of VkQueryPoolCreateInfo::queryType, specifying the type of queries managed by the pool, are:

typedef enum VkQueryType {
    VK_QUERY_TYPE_OCCLUSION =3D 0,
    VK_QUERY_TYPE_PIPELINE_STATISTICS =3D 1,
    VK_QUERY_TYPE_TIMESTAMP =3D 2,
} VkQueryType;

16.2. Query Operation

The operation of queries is controlled by the commands vkCmdBeginQuery, vkCmdEndQuery, vkCmdResetQueryPool, vkCmdCopyQueryPoolResults, and vkCmdWriteTimestamp.

In order for a VkCommandBuffer to record query management c= ommands, the queue family for which its VkCommandPool was created must support the appropriate type of operations (graphics, compute) suitable for the query type of a given query pool.

Each query in a query pool has a status that is either unavailable or available, and also has state to store the numerical results of a = query operation of the type requested when the query pool was created. Resetting a query via vkCmdResetQueryPool sets the= status to unavailable and makes the numerical results undefined. Performing a query operation with vkCmdBeginQuery and vkCmdEndQuery changes the status to available when the q= uery finishes, and updates the numerical results= . Both the availability status and numerical results are retrieved by calling either vkGetQueryPoolResults or vkCmdCopyQueryPoolResults.

Query commands, for the same query and submitted to the same queue, exec= ute in their entirety in submission order= , relative to each other. In effect there is an implicit execution dependency from each such query command to all query command previously submitted to the same queue. There is one significant exception to this; if the flags param= eter of vkCmdCopyQueryPoolResults does not include VK_QUERY_RESULT_WAIT_BIT, execution of vkCmdCopyQueryPoolResults may happen-before the results of vkCmdEndQuery are available.

After query pool creation, each query is in an undefined state and must be reset prior to use. Queries must also be reset between uses. Using a query that has not been reset will result in undefined behavior.

If a logical device includes multiple physical devices, then each comman= d that writes a query must execute on a sin= gle physical device, and any call to vkCmdBeginQuery must execute the corresponding vkCmdEndQuery command on the same physical device.

To reset a range of queries in a query pool, call:

void vkCmdResetQueryPool(
    VkCommandBuffer                             commandBuffer,
    VkQueryPool                                 queryPool,
    uint32_t                                    firstQuery,
    uint32_t                                    queryCount);
  • commandBuffer is the command buffer into which this command= will be recorded.

  • queryPool is the handle of the query pool managing the quer= ies being reset.

  • firstQuery is the initial query index to reset.

  • queryCount is the number of queries to reset.

When executed on a queue, this command sets the status of query indices [firstQuery, firstQuery + queryCount - 1] to unavailable.

Valid Usage
  • firstQuery must be less than= the number of queries in queryPool

  • The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool

Valid Usage (Implicit)
  • co= mmandBuffer must be a valid = VkCommandBuffer handle

  • queryP= ool must be a valid VkQueryP= ool handle

  • co= mmandBuffer must be in the recording state

  • The = VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations=

  • This command must only be called outside of a render pass inst= ance

  • Both of comma= ndBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDe= vice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Gra= phics
Compute

Once queries are reset and ready for use, query commands can be issued to a command buffer. Occlusion queries and pipeline statistics queries count events - drawn samples and pipeline stage invocations, respectively - resulting from commands that are recorded between a vkCmdBeginQuery c= ommand and a vkCmdEndQuery command within a specified command buffer,= effectively scoping a set of drawing and/or compute commands. Timestamp queries write timestamps to a query pool.

A query must begin and end in the same= command buffer, although if it is a primary command buffer, and the inherited queries feature is enable= d, it can execute secondary command buffers = during the query operation. For a secondary command buffer to be executed while a query is active, it must set the occlusionQueryEnable, queryFlags, and/or pipelineStatistics members of = VkCommandBufferInheritanceInfo to conservative values, as described in the Command Buffer Recording section. A query must either begin and end inside = the same subpass of a render pass instance, or must both begin and end outs= ide of a render pass instance (i.e. contain entire render pass instances).

If queries are used while executing a render pass instance that has multiview enabled, the query uses N consecutive q= uery indices in the query pool (starting at query) where N is the number of bits set in the view mask in the subpass the query is used in. How the numerical results of the query are distributed among the queries is implementation-dependent. For example, some implementations may wri= te each view=E2=80=99s results to a distinct query, while other implementations may write the total result to the first query and write zero to the other queries. However, the sum of the results in all the queries must accurately reflect the total result of the query summed over all views. Applications can sum the results from all= the queries to compute the total result.

Queries used with multiview rendering must not span subpasses, i.e. they must begin and end in the same subpass.

To begin a query, call:

void vkCmdBeginQuery(
    VkCommandBuffer                             commandBuffer,
    VkQueryPool                                 queryPool,
    uint32_t                                    query,
    VkQueryControlFlags                         flags);
  • commandBuffer is the command buffer into which this command= will be recorded.

  • queryPool is the query pool that will manage the results of= the query.

  • query is the query index within the query pool that will co= ntain the results.

  • flags is a bitmask of VkQueryContro= lFlagBits specifying constraints on the types of queries that can be performed.

If the queryType of the pool is VK_QUERY_TYPE_OCCLUSI= ON and flags contains VK_QUERY_CONTROL_PRECISE_BIT, an i= mplementation must return a result that matches the act= ual number of samples passed. This is described in more detail in Occlusion Queries.

After beginning a query, that query is considered active within= the command buffer it was called in until that same query is ended. Queries active in a primary command buffer when secondary command buffers are executed are considered active for those secondary command buffers.

Valid Usage
  • queryPool must have been cre= ated with a queryType that differs from that of any queries that are active within commandBuffer

  • All queries used by the command must be u= navailable

  • If the precise occlusion queries feature is not enabled, or the queryType used to c= reate queryPool was not VK_QUERY_TYPE_OCCLUSION, = flags must not contain VK_QUERY_CONTROL_PRECISE_BIT

  • query must be less than the = number of queries in queryPool

  • If the queryType used to create queryPool was VK_QUERY_TYPE_OCCLUSION, the VkCommandPool that commandBuffer was allocated from must= support graphics operations

  • If the queryType used to create queryPool was VK_QUERY_TYPE_PIPELINE_STATISTICS and any of the pipelineStatistics indicate graphics operations, the VkCommandPool that commandBuffer was allocated fr= om must support graphics operations

  • If the queryType used to create queryPool was VK_QUERY_TYPE_PIPELINE_STATISTICS and any of the pipelineStatistics indicate compute operations, the VkCommandPool that commandBuffer was allocated fr= om must support compute operations

  • commandBuffer must not be a = protected command buffer

  • If vkCmdBeginQuery is called within a render pass instance, th= e sum of query and the number of bits set in the current subpass= =E2=80=99s view mask must be less than or equal to t= he number of queries in queryPool

Valid Usage (Implicit)
  • comman= dBuffer must be a valid VkCo= mmandBuffer handle

  • queryPool<= /code> must be a valid VkQueryPool<= /code> handle

  • flags <= strong class=3D"purple">must be a valid combination of VkQueryControlFlagBits values

  • comman= dBuffer must be in the recording state

  • The VkCo= mmandPool that commandBuffer was allocated from must support graphics, or compute operations

  • Both of commandBu= ffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice=

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

Bits which can be set in vkCmdBeginQuery::flags, specifying constraints on the types of queries that can be performed, are:

typedef enum VkQueryControlFlag=
Bits {
    VK_QUERY_CONTROL_PRECISE_BIT =3D 0x00000001,
} VkQueryControlFlagBits;
typedef VkFlags VkQueryControlFlags;

VkQueryControlFlags is a bitmask type for setting a mask of= zero or more VkQueryControlFlagBits.

To end a query after the set of desired draw or dispatch commands is executed, call:

void vkCmdEndQuery(
    VkCommandBuffer                             commandBuffer,
    VkQueryPool                                 queryPool,
    uint32_t                                    query);
  • commandBuffer is the command buffer into which this command= will be recorded.

  • queryPool is the query pool that is managing the results of= the query.

  • query is the query index within the query pool where the re= sult is stored.

As queries operate asynchronously, ending a query does not immediately s= et the query=E2=80=99s status to available. A query is considered finished when the final results of the query= are ready to be retrieved by vkGetQueryPoolResults a= nd vkCmdCopyQueryPoolResults, and this is when = the query=E2=80=99s status is set to available.

Once a query is ended the query must f= inish in finite time, unless the state of the query is changed using other commands, e.g. by issuing a reset of the query.

Valid Usage
  • All queries used by the command must be active

  • query must be less than the = number of queries in queryPool

  • commandBuffer must not be a = protected command buffer

  • If vkCmdEndQuery is called within a render pass instance, the = sum of query and the number of bits set in the current subpass=E2= =80=99s view mask must be less than or equal to the nu= mber of queries in queryPool

Valid Usage (Implicit)
  • commandB= uffer must be a valid VkComm= andBuffer handle

  • queryPool must be a valid VkQueryPool handle

  • commandB= uffer must be in the recording state

  • The VkComm= andPool that commandBuffer was allocated from must support graphics, or compute operations

  • Both of commandBuff= er, and queryPool must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

An application can retrieve results ei= ther by requesting they be written into application-provided memory, or by requesting they be copied into a VkBuffer. In either case, the layout in memory is defined as follows:

  • The first query=E2=80=99s result is written starting at the first byte r= equested by the command, and each subsequent query=E2=80=99s result begins str= ide bytes later.

  • Each query=E2=80=99s result is a tightly packed array of unsigned intege= rs, either 32- or 64-bits as requested by the command, storing the numerical results and, if requested, the availability status.

  • If VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is used, the final element of each query=E2=80=99s result is an integer indicating whether the query=E2=80=99s result is available, with any non-zero value indicating tha= t it is available.

  • Occlusion queries write one integer value - the number of samples passed. Pipeline statistics queries write one integer value for each bit that is enabled in the pipelineStatistics when the pool is created, an= d the statistics values are written in bit order starting from the least significant bit. Timestamps write one integer value.

  • If more than one query is retrieved and stride is not at le= ast as large as the size of the array of integers corresponding to a single query, the values written to memory are undefined.

To retrieve status and results for a set of queries, call:

VkResult vkGetQuer=
yPoolResults(
    VkDevice                                    device,
    VkQueryPool                                 queryPool,
    uint32_t                                    firstQuery,
    uint32_t                                    queryCount,
    size_t                                      dataSize,
    void*                                 =
      pData,
    VkDeviceSize                                stride,
    VkQueryResultFlags                          flags);
  • device is the logical device that owns the query pool.

  • queryPool is the query pool managing the queries containing= the desired results.

  • firstQuery is the initial query index.

  • queryCount is the number of queries. firstQuery and queryCount together define a range= of queries. For pipeline statistics queries, each query index in the pool contains one integer value for each bit that is enabled in VkQueryPoolCreateInfo::pipelineStatistics<= /code> when the pool is created.

  • dataSize is the size in bytes of the buffer pointed to by pData.

  • pData is a pointer to a user-allocated buffer where the res= ults will be written

  • stride is the stride in bytes between results for individua= l queries within pData.

  • flags is a bitmask of VkQueryResultF= lagBits specifying how and when results are returned.

If no bits are set in flags, and all requested queries are = in the available state, results are written as an array of 32-bit unsigned integer values. The behavior when not all queries are available, is described below.

If VK_QUERY_RESULT_64_BIT is not set and the result overflo= ws a 32-bit value, the value may either wrap or satur= ate. Similarly, if VK_QUERY_RESULT_64_BIT is set and the result ove= rflows a 64-bit value, the value may either wrap o= r saturate.

If VK_QUERY_RESULT_WAIT_BIT is set, Vulkan will wait for ea= ch query to be in the available state before retrieving the numerical results for that query. In this case, vkGetQueryPoolResults is guaranteed to succeed a= nd return VK_SUCCESS if the queries become available in a finite = time (i.e. if they have been issued and not reset). If queries will never finish (e.g. due to being reset but not issued), then vkGetQueryPoolResults may no= t return in finite time.

If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTI= AL_BIT are both not set then no result values are written to pData for qu= eries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY. However, availability state is still written to pData for thos= e queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.

Note

Applications must take care to ensure = that use of the VK_QUERY_RESULT_WAIT_BIT bit has the desired effect.

For example, if a query has been used previously and a command buffer records the commands vkCmdResetQueryPool, vkCmdBeginQuer= y, and vkCmdEndQuery for that query, then the query will remain in th= e available state until the vkCmdResetQueryPool command executes= on a queue. Applications can use fences or events to = ensure that a query has already been reset before checking for its results or availability status. Otherwise, a stale value could be returned from a previous use of the query= .

The above also applies when VK_QUERY_RESULT_WAIT_BIT is use= d in combination with VK_QUERY_RESULT_WITH_AVAILABILITY_BIT. In this case, the returned availability status may= reflect the result of a previous use of the query unless the vkCmdResetQueryPool comma= nd has been executed since the last use of the query.

Note

Applications can double-buffer query p= ool usage, with a pool per frame, and reset queries at the end of the frame in which they are read.

If VK_QUERY_RESULT_PARTIAL_BIT is set, VK_QUERY_RESUL= T_WAIT_BIT is not set, and the query=E2=80=99s status is unavailable, an intermediate = result value between zero and the final result value is written to pData for that query.

VK_QUERY_RESULT_PARTIAL_BIT must not be used if the pool=E2=80=99s queryType is VK_QUERY_TYPE_TIMESTAMP.

If VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set, the final = integer value written for each query is non-zero if the query=E2=80=99s status was = available or zero if the status was unavailable. When VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is used, implementa= tions must guarantee that if they return a non-= zero availability value then the numerical results must be valid, assuming= the results are not reset by a subsequent command.

Note

Satisfying this guarantee may require = careful ordering by the application, e.g. to read the availability status before reading the results.

Valid Usage
  • firstQuery must be less than= the number of queries in queryPool

  • If VK_QUERY_RESULT_64_BIT is not set in flags the= n pData and stride must be multiples of 4

  • If VK_QUERY_RESULT_64_BIT is set in flags then pData and stride must be multiples= of 8

  • The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool

  • dataSize must be large enoug= h to contain the result of each query, as described here

  • If the queryType used to create queryPool was VK_QUERY_TYPE_TIMESTAMP, flags must not contain VK_QUERY_RESULT_PARTIAL_BIT

Valid Usage (Implicit)
  • device<= /code> must be a valid VkDevice handle

  • quer= yPool must be a valid VkQuer= yPool handle

  • pData must be a valid pointer to an array = of dataSize bytes

  • flags must be a valid combination of VkQueryResultFlagBits values

  • dat= aSize must be greater than 0=

  • queryPo= ol must have been created, allocat= ed, or retrieved from device

Return Codes
Success
  • VK_SUCCESS

  • VK_NOT_READY

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

Bits which can be set in vkGetQueryPoolResults::flags and vkCmdCopyQueryPoolResults::flags, specifying how and when results are returned, are:

typedef enum VkQueryResultFlagB=
its {
    VK_QUERY_RESULT_64_BIT =3D 0x00000001,
    VK_QUERY_RESULT_WAIT_BIT =3D 0x00000002,
    VK_QUERY_RESULT_WITH_AVAILABILITY_BIT =3D 0x0000000=
4,
    VK_QUERY_RESULT_PARTIAL_BIT =3D 0x00000008,
} VkQueryResultFlagBits;
  • VK_QUERY_RESULT_64_BIT specifies the results will be writte= n as an array of 64-bit unsigned integer values. If this bit is not set, the results will be written as an array of 32-bit unsigned integer values.

  • VK_QUERY_RESULT_WAIT_BIT specifies that Vulkan will wait fo= r each query=E2=80=99s status to become available before retrieving its results.

  • VK_QUERY_RESULT_WITH_AVAILABILITY_BIT specifies that the availability status accompanies the results.

  • VK_QUERY_RESULT_PARTIAL_BIT specifies that returning partia= l results is acceptable.

typedef VkFlags VkQueryResultFlags;

VkQueryResultFlags is a bitmask type for setting a mask of = zero or more VkQueryResultFlagBits.

To copy query statuses and numerical results directly to buffer memory, call:

void vkCmdCopyQueryPoolResults(
    VkCommandBuffer                             commandBuffer,
    VkQueryPool                                 queryPool,
    uint32_t                                    firstQuery,
    uint32_t                                    queryCount,
    VkBuffer                                    dstBuffer,
    VkDeviceSize                                dstOffset,
    VkDeviceSize                                stride,
    VkQueryResultFlags                          flags);
  • commandBuffer is the command buffer into which this command= will be recorded.

  • queryPool is the query pool managing the queries containing= the desired results.

  • firstQuery is the initial query index.

  • queryCount is the number of queries. firstQuery and queryCount together define a range= of queries.

  • dstBuffer is a VkBuffer object that will rece= ive the results of the copy command.

  • dstOffset is an offset into dstBuffer.

  • stride is the stride in bytes between results for individua= l queries within dstBuffer. The required size of the backing memory for dstBuffer is determined as described above for vkGetQueryPoolResu= lts.

  • flags is a bitmask of VkQueryResultF= lagBits specifying how and when results are returned.

vkCmdCopyQueryPoolResults is guaranteed to see the effect o= f previous uses of vkCmdResetQueryPool in the same queue, without any add= itional synchronization. Thus, the results will always reflect the most recent use of the query.

flags has the same possible values described above for the = flags parameter of vkGetQueryPoolResults, but the diff= erent style of execution causes some subtle behavioral differences. Because vkCmdCopyQueryPoolResults executes in order with respe= ct to other query commands, there is less ambiguity about which use of a query is being requested.

If no bits are set in flags, results for all requested quer= ies in the available state are written as 32-bit unsigned integer values, and nothing is written for queries in the unavailable state.

If VK_QUERY_RESULT_64_BIT is set, the results are written a= s an array of 64-bit unsigned integer values as described for vkGetQueryPoolResults.

If VK_QUERY_RESULT_WAIT_BIT is set, the implementation will= wait for each query=E2=80=99s status to be in the available state before retrieving = the numerical results for that query. This is guaranteed to reflect the most recent use of the query on the same queue, assuming that the query is not being simultaneously used by other queues. If the query does not become available in a finite amount of time (e.g. due to not issuing a query since the last reset), a VK_ERROR_DEVICE_LOST<= /code> error may occur.

Similarly, if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set = and VK_QUERY_RESULT_WAIT_BIT is not set, the availability is guara= nteed to reflect the most recent use of the query on the same queue, assuming that the query is not being simultaneously used by other queues. As with vkGetQueryPoolResults, implementations must guarantee that if they return a non-zero availability value, then the numerical results are valid.

If VK_QUERY_RESULT_PARTIAL_BIT is set, VK_QUERY_RESUL= T_WAIT_BIT is not set, and the query=E2=80=99s status is unavailable, an intermediate = result value between zero and the final result value is written for that query.

VK_QUERY_RESULT_PARTIAL_BIT must not be used if the pool=E2=80=99s queryType is VK_QUERY_TYPE_TIMESTAMP.

vkCmdCopyQueryPoolResults is considered to be a transfer op= eration, and its writes to buffer memory must be s= ynchronized using VK_PIPELINE_STAGE_TRANSFER_BIT and VK_ACCESS_TRANSFER_WR= ITE_BIT before using the results.

Valid Usage
  • dstOffset must be less than = the size of dstBuffer

  • firstQuery must be less than= the number of queries in queryPool

  • The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool

  • If VK_QUERY_RESULT_64_BIT is not set in flags the= n dstOffset and stride mus= t be multiples of 4

  • If VK_QUERY_RESULT_64_BIT is set in flags then dstOffset and stride mus= t be multiples of 8

  • dstBuffer must have enough s= torage, from dstOffset, to contain the result of each query, as described here

  • dstBuffer must have been cre= ated with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag

  • If dstBuffer is non-sparse then it mu= st be bound completely and contiguously to a single VkDeviceMemory object

  • If the queryType used to create queryPool was VK_QUERY_TYPE_TIMESTAMP, flags must not contain VK_QUERY_RESULT_PARTIAL_BIT

Valid Usage (Implicit)
  • commandBuffer must be a valid = VkCommandBuffer handle

  • = queryPool must be a valid Vk= QueryPool handle

  • = dstBuffer must be a valid Vk= Buffer handle

  • flag= s must be a valid combination of <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kQueryResultFlagBits">VkQueryResultFlagBits values

  • commandBuffer must be in the <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#c= ommandbuffers-lifecycle">recording state

  • The = VkCommandPool that commandBuffer was allocated fr= om must support graphics, or compute oper= ations

  • This command must only be called outside of a render pas= s instance

  • Each of commandBuffer, dstBuffer, and queryPool <= strong class=3D"purple">must have been created, allocated, or retr= ieved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Gra= phics
Compute

Tra= nsfer

Rendering operations such as clears, MSAA resolves, attachment load/stor= e operations, and blits may count towards t= he results of queries. This behavior is implementation-dependent and may<= /strong> vary depending on the path used within an implementation. For example, some implementations have several types of clears, some of which may include vertices and some not.<= /p>

16.3. Occlusion Queries

Occlusion queries track the number of samples that pass the per-fragment tests for a set of drawing commands. As such, occlusion queries are only available on queue families supporting graphics operations. The application can then use these result= s to inform future rendering decisions. An occlusion query is begun and ended by calling vkCmdBeginQuery and vkCmdEndQuery, respectively. When an occlusion query begins, the count of passing samples always starts at zero. For each drawing command, the count is incremented as described in Sample Counting. If flags does not contain VK_QUERY_CONTROL_PRECISE_BIT an implementation may generate any non-zero = result value for the query if the count of passing samples is non-zero.

Note

Not setting VK_QUERY_CONTROL_PRECISE_BIT mode may be more efficient on some implementations, and should be us= ed where it is sufficient to know a boolean result on whether any samples passed the per-fragment tests. In this case, some implementations may on= ly return zero or one, indifferent to the actual number of samples passing the per-fragment tests.

When an occlusion query finishes, the result for that query is marked as available. The application can then either copy the = result to a buffer (via vkCmdCopyQueryPoolResults) or request it be put into host memo= ry (via vkGetQueryPoolResults).

Note

If occluding geometry is not drawn first, samples can pass the depth test, but still not be visible in a final image.

16.4. Pipeline Statistics Queries

Pipeline statistics queries allow the application to sample a specified = set of VkPipeline counters. These counters are accumulated by Vulkan for a set of either draw or dispatch commands while a pipeline statistics query is active. As such, pipeline statistics queries are available on queue families supporting either graphics or compute operations. Further, the availability of pipeline statistics queries is indicated by th= e pipelineStatisticsQuery member of the VkPhysicalDeviceFe= atures object (see vkGetPhysicalDeviceFeatures and vkCreateDevi= ce for detecting and requesting this query type on a VkDevice).

A pipeline statistics query is begun and ended by calling vkCmdBeginQuery and vkCmdEndQuery, respectively. When a pipeline statistics query begins, all statistics counters are set to zero. While the query is active, the pipeline type determines which set of statistics are available, but these must = be configured on the query pool when it is created. If a statistic counter is issued on a command buffer that does not support the corresponding operation, that counter is undefined after the query has finished. At least one statistic counter relevant to the operations supported on the recording command buffer must be enabled.=

Bits which can be set to individually = enable pipeline statistics counters for query pools with VkQueryPoolCreateInfo::pipelineStatistics, and for secondary command buffers with VkCommandBufferInheritanceInfo::p= ipelineStatistics, are:

typedef enum VkQueryPipelineSta=
tisticFlagBits {
    VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT =3D 0x00000001,
    VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT =3D 0x00000002,
    VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT =3D 0x00000004,
    VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT =3D 0x00000008,
    VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT =3D 0x00000010,
    VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT =3D 0x00000020,
    VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT =3D 0x00000040,
    VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT =3D 0x00000080,
    VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT =3D=
 0x00000100,
    VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_=
BIT =3D 0x00000200,
    VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT =3D 0x00000400,
} VkQueryPipelineStatisticFlagBits;
  • VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT spe= cifies that queries managed by the pool will count the number of vertices processed by the input assembly stage. Vertices corresponding to incomplete primitives ma= y contribute to the count.

  • VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT specifies that queries managed by the pool will count the number of primitives processed by the input assembly stage. If primitive restart is enabled, restarting the primitive topology has no effect on the count. Incomplete primitives may be counted.

  • VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT specifies that queries managed by the pool will count the number of vertex shader invocations. This counter=E2=80=99s value is incremented each time a vertex shader is invoked.

  • VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT specifies that queries managed by the pool will count the number of geometry shader invocations. This counter=E2=80=99s value is incremented each time a geometry shader is invoked. In the case of instanced geometry shaders, the geometry shader invocations count is incremented for each separate instanced invocation.

  • VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT specifies that queries managed by the pool will count the number of primitives generated by geometry shader invocations. The counter=E2=80=99s value is incremented each time the geometry shader em= its a primitive. Restarting primitive topology using the SPIR-V instructions OpEndPrimitive or OpEndStreamPrimitive has no eff= ect on the geometry shader output primitives count.

  • VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT specif= ies that queries managed by the pool will count the number of primitives processed by the Primitive Clipping stage of the pipeline. The counter=E2=80=99s value is incremented each time a primitive reaches th= e primitive clipping stage.

  • VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT specifi= es that queries managed by the pool will count the number of primitives output by the Primitive Clipping stage of the pipeline. The counter=E2=80=99s value is incremented each time a primitive passes the primitive clipping stage. The actual number of primitives output by the primitive clipping stage for a particular input primitive is implementation-dependent but must satisfy the following conditions:

    • If at least one vertex of the input primitive lies inside the clipping volume, the counter is incremented by one or more.

    • Otherwise, the counter is incremented by zero or more.

  • VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT specifies that queries managed by the pool will count the number of fragment shader invocations. The counter=E2=80=99s value is incremented each time the fragment shader is invoked.

  • VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BI= T specifies that queries managed by the pool will count the number of patches processed by the tessellation control shader. The counter=E2=80=99s value is incremented once for each patch for which a tessellation control shader is invoked.

  • VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCAT= IONS_BIT specifies that queries managed by the pool will count the number of invocations of the tessellation evaluation shader. The counter=E2=80=99s value is incremented each time the tessellation evalu= ation shader is invoked.

  • VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT specifies that queries managed by the pool will count the number of compute shader invocations. The counter=E2=80=99s value is incremented every time the compute shader is invoked. Implementations may skip the execution of= certain compute shader invocations or execute additional compute shader invocations for implementation-dependent reasons as long as the results of rendering otherwise remain unchanged.

These values are intended to measure relative statistics on one implementation. Various device architectures will count these values differently. Any or all counters may be affected by th= e issues described in Query Operation.

Note

For example, tile-based rendering devices may need to replay the scene multiple times, affecting some of the counts.

If a pipeline has rasterizerDiscardEnable enabled, implemen= tations may discard primitives after the final ve= rtex processing stage. As a result, if rasterizerDiscardEnable is enabled, the clippi= ng input and output primitives counters may not be= incremented.

When a pipeline statistics query finishes, the result for that query is marked as available. The application can copy the result to a = buffer (via vkCmdCopyQueryPoolResults), or request it be put into host mem= ory (via vkGetQueryPoolResults).

typedef VkFlags VkQueryPipelineStatisticFlags;

VkQueryPipelineStatisticFlags is a bitmask type for setting= a mask of zero or more VkQueryPipelineStatisticFlag= Bits.

16.5. Timestamp Queries

Timestamps provide applications with a mechanism for timing the= execution of commands. A timestamp is an integer value generated by the VkPhysicalDevice. Unlike other queries, timestamps do not operate over a range, and so do not use vkCmdBeginQuery or vkCmdEndQuery. The mechanism is built around a set of commands that allow the application to tell the VkPhysicalDevice to write timestamp values to a query pool and then either read timestamp values on the host (using vkGetQueryPoolResults) or copy times= tamp values to a VkBuffer (using vkCmdCopyQueryPoolR= esults). The application can then compute differen= ces between timestamps to determine execution time.

The number of valid bits in a timestamp value is determined by the VkQueueFamilyProperties::timestampValidBits prope= rty of the queue on which the timestamp is written. Timestamps are supported on any queue which reports a non-zero value for timestampValidBits via vkGetPhysicalDeviceQueueFamilyProperties. If the timestampComputeA= ndGraphics limit is VK_TRUE, timestamps are supported by every queue family that supports either graphics or compute operations (see VkQueueFamilyProperties).

The number of nanoseconds it takes for a timestamp value to be increment= ed by 1 can be obtained from VkPhysicalDeviceLimits::timestampPeriod after a c= all to vkGetPhysicalDeviceProperties.

To request a timestamp, call:

void vkCmdWriteTimestamp(
    VkCommandBuffer                             commandBuffer,
    VkPipelineStageFlagBits                     pipelineStage,
    VkQueryPool                                 queryPool,
    uint32_t                                    query);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • pipelineStage is one of the VkPipe= lineStageFlagBits, specifying a stage of the pipeline.

  • queryPool is the query pool that will manage the timestamp.=

  • query is the query within the query pool that will contain = the timestamp.

vkCmdWriteTimestamp latches the value of the timer when all= previous commands have completed executing as far as the specified pipeline stage, and writes the timestamp value to memory. When the timestamp value is written, the availability status of the query i= s set to available.

Note

If an implementation is unable to detect completion and latch the timer = at any specific stage of the pipeline, it may instead do so at any logically later stage.

vkCmdCopyQueryPoolResults can then be called to copy the timestamp value from the query pool into buffer memory, with ordering and synchronization behavior equivalent to how other queries operate. Timestamp values can also be retrieved fr= om the query pool using vkGetQueryPoolResults. As with other queries, the query must be = reset using vkCmdResetQueryPool before requesting the timestam= p value be written to it.

While vkCmdWriteTimestamp can be called inside or outside of a render pass instance, vkCmdCopyQueryPoolResults must only be called outside of a render pass instance.

Timestamps may only be meaningfully co= mpared if they are written by commands submitted to the same queue.

Note

An example of such a comparison is determining the execution time of a sequence of commands.

If vkCmdWriteTimestamp is called while executing a render p= ass instance that has multiview enabled, the timestamp uses = N consecutive query indices in the query pool (starting at query) where N is the number of bits set in the view mask of the subpass the command is executed in. The resulting query values are determined by an implementation-dependent choice of one of the following behaviors:

  • The first query is a timestamp value and (if more than one bit is set in the view mask) zero is written to the remaining queries. If two timestamps are written in the same subpass, the sum of the execution time of all views between those commands is the difference between the first query written by each command.

  • All N queries are timestamp values. If two timestamps are written in the same subpass, the sum of the execution time of all views between those commands is the sum of the difference between corresponding queries written by each command. The difference between corresponding queries may be the execution time of a single view.

In either case, the application can su= m the differences between all N queries to determine the total execution time.

Valid Usage
  • queryPool must have been cre= ated with a queryType of VK_QUERY_TYPE_TIMESTAMP

  • The query identified by queryPool and query must be unavailable

  • The command pool=E2=80=99s queue family must support a non-zero timestampValidBits

  • All queries used by the command must be u= navailable

  • If vkCmdWriteTimestamp is called within a render pass instance= , the sum of query and the number of bits set in the current subpass=E2=80=99s view mask must be less = than or equal to the number of queries in queryPool

Valid Usage (Implicit)
  • co= mmandBuffer must be a valid = VkCommandBuffer handle

  • pi= pelineStage must be a valid VkPipelineStageFlagBits value

  • queryP= ool must be a valid VkQueryP= ool handle

  • co= mmandBuffer must be in the recording state

  • The = VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute = operations

  • Both of comma= ndBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDe= vice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Tra= nsfer
Graphics
Compute

Tra= nsfer

17. Clear Commands

17.1. Clearing Images Outside A Render Pass Insta= nce

Color and depth/stencil images can be = cleared outside a render pass instance using vkCmdClearColorImage or vkCmdClearDepthStencilImage, respectively. These commands are only allowed outside of a render pass instance.

To clear one or more subranges of a color image, call:

void vkCmdClearColorImage(
    VkCommandBuffer                             commandBuffer,
    VkImage                                     image,
    VkImageLayout                               imageLayout,
    const VkClearColorValue*              =
      pColor,
    uint32_t                                    rangeCount,
    const VkImageSubresourceRange*        =
      pRanges);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • image is the image to be cleared.

  • imageLayout specifies the current layout of the image subre= source ranges to be cleared, and must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.

  • pColor is a pointer to a VkClearColorVal= ue structure that contains the values the image subresource ranges will be cleared to (see Clear Values below).

  • rangeCount is the number of image subresource range structu= res in pRanges.

  • pRanges points to an array of VkIm= ageSubresourceRange structures that describe a range of mipmap levels, array layers, and aspects to be cleared, as described in Image Views. The aspectMask of all image subresource ranges must only include VK_IMAGE_ASPECT_COLOR_BIT.

Each specified range in pRanges is cleared to the value spe= cified by pColor.

Valid Usage
Valid Usage (Implicit)
  • c= ommandBuffer must be a valid VkCommandBuffer handle

  • image must be a valid VkImage = handle

  • ima= geLayout must be a valid VkImageLayout value

  • pColor must be a valid pointer to a valid = VkClearColorValue union

  • pRanges= must be a valid pointer to an arr= ay of rangeCount valid VkImageSubresourceRange st= ructures

  • c= ommandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operation= s

  • This command must only be called outside of a render pass ins= tance

  • ra= ngeCount must be greater than 0

  • Both of comm= andBuffer, and image must have been created, allocated, or retrieved from the same VkDevic= e

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Gra= phics
Compute

Tra= nsfer

To clear one or more subranges of a depth/stencil image, call:

void vkCmdClearDepthStencilImage(
    VkCommandBuffer                             commandBuffer,
    VkImage                                     image,
    VkImageLayout                               imageLayout,
    const VkClearDepthStencilValue*       =
      pDepthStencil,
    uint32_t                                    rangeCount,
    const VkImageSubresourceRange*        =
      pRanges);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • image is the image to be cleared.

  • imageLayout specifies the current layout of the image subre= source ranges to be cleared, and must be V= K_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.

  • pDepthStencil is a pointer to a V= kClearDepthStencilValue structure that contains the values the depth and stencil image subresource ranges will be cleared to (see Clear Values = below).

  • rangeCount is the number of image subresource range structu= res in pRanges.

  • pRanges points to an array of VkIm= ageSubresourceRange structures that describe a range of mipmap levels, array layers, and aspects to be cleared, as described in Image Views. The aspectMask of each image subresource range in pRange= s can include VK_IMAGE_ASPECT_DEPTH_B= IT if the image format has a depth component, and VK_IMAGE_ASPECT_STENCIL_BIT if the image format has a stencil component.

Valid Usage
  • The format features of image must contain VK_FORMAT_FEATURE_TRAN= SFER_DST_BIT.

  • image must have been created= with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag

  • If image is non-sparse then it must be bound completely and contiguously to a single VkDeviceMemory object

  • imageLayout must specify the= layout of the image subresource ranges of image specified in pRanges at the time = this command is executed on a VkDevice

  • imageLayout must be either o= f VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

  • The VkImageSubresourceRange::baseMipLeve= l members of the elements of the pRanges array must each be less than the mipLevels specified in VkImageCreateInfo when image was created

  • For each VkImageSubresourceRange element of pRanges, if the levelCount member is not VK_REMAINING_MIP_LEVELS,= then baseMipLevel + levelCount must be less than the mipLevels specified in VkImageCreateInfo when image was created

  • The VkImageSubresourceRange::baseArrayLa= yer members of the elements of the pRanges array must each be less than the arrayLayers specified in VkImageCreateInfo<= /a> when image was created

  • For each VkImageSubresourceRange element of pRanges, if the layerCount member is not VK_REMAINING_ARRAY_LAYERS, then baseArrayLayer + layerCount must be less than the arrayLayers specified in VkImageCreateI= nfo when image was created

  • image must have a depth/sten= cil format

  • If commandBuffer is an unprotected command buffer, then image must not be a protecte= d image

  • If commandBuffer is a protected command buffer, then ima= ge must not be an unprotected image

Valid Usage (Implicit)
  • = commandBuffer must be a vali= d VkCommandBuffer handle

  • im= age must be a valid VkImage<= /code> handle

  • imageLayout must be a valid VkImageLayout value

  • = pDepthStencil must be a vali= d pointer to a valid VkClearDepthStencilValue structure

  • = pRanges must be a valid pointer to= an array of rangeCount valid VkImageSubresourceRange structures

  • = commandBuffer must be in the= recording state

  • Th= e VkCommandPool that commandBuffer was allocated = from must support graphics operations

  • This command = must only be called outside of a render p= ass instance

  • <= code>rangeCount must be greater th= an 0

  • Both of commandBuffer, and image mu= st have been created, allocated, or retrieved from the same = VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Gra= phics

Tra= nsfer

Clears outside render pass instances are treated as transfer operations = for the purposes of memory barriers.

17.2. Clearing Images Inside A Render Pass Instanc= e

To clear one or more regions of color and depth/stencil attachments insi= de a render pass instance, call:

void vkCmdClearAttachments(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    attachmentCount,
    const VkClearAttachment*              =
      pAttachments,
    uint32_t                                    rectCount,
    const VkClearRect*                    =
      pRects);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • attachmentCount is the number of entries in the pAtta= chments array.

  • pAttachments is a pointer to an array of VkClearAttachment structures defining the attachments to clear and the clear values to use.

  • rectCount is the number of entries in the pRects array.

  • pRects points to an array of VkClearRect s= tructures defining regions within each selected attachment to clear.

vkCmdClearAttachments can= clear multiple regions of each attachment used in the current subpass of a render pass instance. This command must be called only inside a= render pass instance, and implicitly selects the images to clear based on the current framebuffer attachments and the command parameters.

Valid Usage
  • If the aspectMask member of any element of pAttachments<= /code> contains VK_IMAGE_ASPECT_COLOR_BIT, the colorAttachment<= /code> member of that element must refer to a va= lid color attachment in the current subpass

  • The rectangular region specified by each element of pRects must be contained within the render area of the current render pass instance

  • The layers specified by each element of pRects must be contained within every attachment that pAttachments refers to

  • The layerCount member of each element of pRects <= strong class=3D"purple">must not be 0

  • If the render pass instance this is recorded in uses multiview, then baseArrayLayer must be zero = and layerCount must be one.<= /p>

Valid Usage (Implicit)
  • = commandBuffer must be a valid VkCommandBuffer handle

  • p= Attachments must be a valid pointe= r to an array of attachmentCount valid VkClearAttachment= structures

  • pRects<= /code> must be a valid pointer to an arra= y of rectCount VkClearRect structures

  • = commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from <= strong class=3D"purple">must support graphics operations

  • This command must only be called inside of a render pass ins= tance

  • attachmentCount must be greate= r than 0

  • re= ctCount must be greater than 0

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

The VkClearRect structure is defined as:

typedef struct VkClearRect {
    VkRect2D    rect;
    uint32_t    baseArrayLayer;
    uint32_t    layerCount;
} VkClearRect;
  • rect is the two-dimensional region to be cleared.

  • baseArrayLayer is the first layer to be cleared.

  • layerCount is the number of layers to clear.

The layers [baseArrayLayer, baseAr= rayLayer +=20 layerCount) counting from the base layer of the attachm= ent image view are cleared.

The VkClearAttachment structure is defined as:

typedef struct VkClearAttachmen=
t {
    VkImageAspectFlags    aspectMask;
    uint32_t              colorAttachment;
    VkClearValue          clearValue;
} VkClearAttachment;
  • aspectMask is a mask selecting the color, depth and/or sten= cil aspects of the attachment to be cleared. aspectMask can include VK_IMAGE_ASPECT_COLOR_BIT for color attachments, VK_IMAGE_ASPECT_DEPTH_BIT for depth/stencil attachments with a depth component, and VK_IMAGE_ASPECT_STENCIL_BIT for depth/stencil attachments with= a stencil component. If the subpass=E2=80=99s depth/stencil attachment is VK_ATTACHMENT_UN= USED, then the clear has no effect.

  • colorAttachment is only meaningful if VK_IMAGE_ASPECT_COLOR_BIT is set in aspectMask, i= n which case it is an index to the pColorAttachments array in the VkSubpassDescription structure of the current sub= pass which selects the color attachment to clear. If colorAttachment is VK_ATTACHMENT_UNUSED then t= he clear has no effect.

  • clearValue is the color or depth/stencil value to clear the attachment to, as described in Clear Values below.

No memory barriers are needed between vkCmdClearAttachments= and preceding or subsequent draw or attachment clear commands in the same subpass.

The vkCmdClearAttachments command is not affected by the bo= und pipeline state.

Attachments can also be cleared at the= beginning of a render pass instance by setting loadOp (or stencilLoadOp) of VkAttachmentDescription to VK_ATTACHMENT= _LOAD_OP_CLEAR, as described for vkCreateRenderPass.

Valid Usage
  • If aspectMask includes VK_IMAGE_ASPECT_COLOR_BIT,= it must not include VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT

  • aspectMask must not include = VK_IMAGE_ASPECT_METADATA_BIT

  • clearValue must be a valid <= code>VkClearValue union

  • If commandBuffer is an unprotected command buffer, then the attachment to be cleared must not be a pr= otected image.

  • If commandBuffer is a protected command buffer, then the attachment to be cleared must not be an u= nprotected image.

Valid Usage (Implicit)

17.3. Clear Values

The VkClearColorValue structure is defined as:

typedef union VkClearColorValue=
 {
    float       float32[4];
    int32_t     int32[4];
    uint32_t    uint32[4];
} VkClearColorValue;
  • float32 are the color clear values when the format of the i= mage or attachment is one of the formats in the Interpretation of Numeric Format table other than signed integer (SINT) or unsigned integer (UINT). Floating point values are automatically converted to the format of the image, with the clear value being treated as linear if the image is sRGB.

  • int32 are the color clear values when the format of the ima= ge or attachment is signed integer (SINT). Signed integer values are converted to the format of the image by casting to the smaller type (with negative 32-bit values mapping to negative values in the smaller type). If the integer clear value is not representable in the target type (e.g. would overflow in conversion to that type), the clear value is undefined.

  • uint32 are the color clear values when the format of the im= age or attachment is unsigned integer (UINT). Unsigned integer values are converted to the format of the image by casting to the integer type with fewer bits.

The four array elements of the clear color map to R, G, B, and A compone= nts of image formats, in order.

If the image has more than one sample, the same value is written to all samples for any pixels being cleared.

The VkClearDepthStencilValue structure is defined as:

typedef struct VkClearDepthSten=
cilValue {
    float       depth;
    uint32_t    stencil;
} VkClearDepthStencilValue;
  • depth is the clear value for the depth aspect of the depth/= stencil attachment. It is a floating-point value which is automatically converted to the attachment=E2=80=99s format.

  • stencil is the clear value for the stencil aspect of the depth/stencil attachment. It is a 32-bit integer value which is converted to the attachment=E2=80=99s format by taking the appropriate number of LSBs.

Valid Usage

The VkClearValue union is defined as:

typedef union VkClearValue {
    VkClearColorValue           color;
    VkClearDepthStencilValue    depthStencil;
} VkClearValue;
  • color specifies the color image clear values to use when cl= earing a color image or attachment.

  • depthStencil specifies the depth and stencil clear values t= o use when clearing a depth/stencil image or attachment.

This union is used where part of the API requires either color or depth/stencil clear values, depending on the attachment, and defines the initial clear values in the VkRenderPassBeginInfo structure.

17.4. Filling Buffers

To clear buffer data, call:

void vkCmdFillBuffer(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    dstBuffer,
    VkDeviceSize                                dstOffset,
    VkDeviceSize                                size,
    uint32_t                                    data);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • dstBuffer is the buffer to be filled.

  • dstOffset is the byte offset into the buffer at which to st= art filling, and must be a multiple of 4.

  • size is the number of bytes to fill, and must be either a multiple of 4, or VK_WHOLE_SIZE to fill the range from offset to the end of the buffer. If VK_WHOLE_SIZE is used and the remaining size of the buffer = is not a multiple of 4, then the nearest smaller multiple is used.

  • data is the 4-byte word written repeatedly to the buffer to= fill size bytes of data. The data word is written to memory according to the host endianness.

vkCmdFillBuffer is treated as =E2=80=9Ctransfer=E2=80=9D op= eration for the purposes of synchronization barriers. The VK_BUFFER_USAGE_TRANSFER_DST_BIT = must be specified in usage of VkBufferCreateInfo in order for the buffer to be compatible= with vkCmdFillBuffer.

Valid Usage
  • dstOffset must be less than = the size of dstBuffer

  • dstOffset must be a multiple= of 4

  • If size is not equal to VK_WHOLE_SIZE, size= must be greater than 0

  • If size is not equal to VK_WHOLE_SIZE, size= must be less than or equal to the size of dstBuffer minus dstOff= set

  • If size is not equal to VK_WHOLE_SIZE, size= must be a multiple of 4

  • dstBuffer must have been cre= ated with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag

  • If dstBuffer is non-sparse then it mu= st be bound completely and contiguously to a single VkDeviceMemory object

  • If commandBuffer is an unprotected command buffer, then dstBuffer must not be a prot= ected buffer

  • If commandBuffer is a protected command buffer, then dstBuffer must not be an unp= rotected buffer

Valid Usage (Implicit)
  • comman= dBuffer must be a valid VkCo= mmandBuffer handle

  • dstBuffer<= /code> must be a valid VkBuffer handle

  • comman= dBuffer must be in the recording state

  • The VkCo= mmandPool that commandBuffer was allocated from must support transfer, graphics or compute opera= tions

  • This command must only be called outside of a render pass instance=

  • Both of commandBu= ffer, and dstBuffer must have been created, allocated, or retrieved from the same VkDevice=

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Tra= nsfer
Graphics
Compute

Tra= nsfer

17.5. Updating Buffers

To update buffer data inline in a command buffer, call:

void vkCmdUpdateBuffer(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    dstBuffer,
    VkDeviceSize                                dstOffset,
    VkDeviceSize                                dataSize,
    const void*                                 pData);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • dstBuffer is a handle to the buffer to be updated.

  • dstOffset is the byte offset into the buffer to start updat= ing, and must be a multiple of 4.

  • dataSize is the number of bytes to update, and must be a multiple of 4.

  • pData is a pointer to the source data for the buffer update= , and must be at least dataSize by= tes in size.

dataSize must be less tha= n or equal to 65536 bytes. For larger updates, applications can use = buffer to buffer copies.

Note

Buffer updates performed with vkCmdUpdateBuffer first copy = the data into command buffer memory when the command is recorded (which requires additional storage and may incur an additional allocation), and then copy the data from the command buffer into dstBuffer when the comma= nd is executed on a device.

The additional cost of this functionality compared to bu= ffer to buffer copies means it is only recommended for very small amounts of data, and is why it is limited to only 65536 bytes.

Applications can work around this by i= ssuing multiple vkCmdUpdateBuffer commands to different ranges of the same buf= fer, but it is strongly recommended that they should not.

The source data is copied from the user pointer to the command buffer wh= en the command is called.

vkCmdUpdateBuffer is only allowed outside of a render pass. This command is treated as =E2=80=9Ctransfer=E2=80=9D operation, for the pu= rposes of synchronization barriers. The VK_BUFFER_USAGE_TRANSFER_DST_BIT = must be specified in usage of VkBufferCreateInfo in order for the buffer to be= compatible with vkCmdUpdateBuffer.

Valid Usage
  • dstOffset must be less than = the size of dstBuffer

  • dataSize must be less than o= r equal to the size of dstBuffer minus dstOffset

  • dstBuffer must have been cre= ated with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag

  • If dstBuffer is non-sparse then it mu= st be bound completely and contiguously to a single VkDeviceMemory object

  • dstOffset must be a multiple= of 4

  • dataSize must be less than o= r equal to 65536

  • dataSize must be a multiple = of 4

  • If commandBuffer is an unprotected command buffer, then dstBuffer must not be a prot= ected buffer

  • If commandBuffer is a protected command buffer, then dstBuffer must not be an unp= rotected buffer

Valid Usage (Implicit)
  • comm= andBuffer must be a valid Vk= CommandBuffer handle

  • dstBuffe= r must be a valid VkBuffer handle

  • pData= must be a valid pointer to an array of <= code>dataSize bytes

  • comm= andBuffer must be in the recording state

  • The Vk= CommandPool that commandBuffer was allocated from must support transfer, graphics, or compute op= erations

  • This command must only be called outside of a render pass instan= ce

  • dataSiz= e must be greater than 0

  • Both of command= Buffer, and dstBuffer must have been created, allocated, or retrieved from the same VkDevi= ce

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Tra= nsfer
Graphics
Compute

Tra= nsfer

Note

The pData parameter was of type uint32_t* inst= ead of void* prior to revision 1.0.19 of the Specification and VK_HEA= DER_VERSION 19 of the Vulkan Header Files. This was a historical anomaly, as the source data may be of other types.

18. Copy Commands

An application can copy buffer and ima= ge data using several methods depending on the type of data transfer. Data can be copied between buffer objects= with vkCmdCopyBuffer and a portion of an image can be copied to anot= her image with vkCmdCopyImage. Image data can also be copied to and from= buffer memory using vkCmdCopyImageToBuffer and vkCmdCopyBufferToImage= . Image data can be blitted (with or withou= t scaling and filtering) with vkCmdBlitImage. Multisampled images can be resolved to a = non-multisampled image with vkCmdResolveImage.

18.1. Common Operation

The following valid usage rules apply to all copy commands:

  • Copy commands must be recorded outside= of a render pass instance.

  • The set of all bytes bound to all the source regions must not overlap the set of all bytes bound to the destination regions.

  • The set of all bytes bound to each destination region must not overlap the set of all bytes bound to another destination region.

  • Copy regions must be non-empty.

  • Regions must not extend outside the bo= unds of the buffer or image level, except that regions of compressed images ca= n extend as far as the dimension of the image level rounded up to a complete compressed texel block.

  • Source image subresources must be in e= ither the VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL layout. Destination image subresources must be in= the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL layout. As a consequence, if an image subresource is used as both source and destination of a copy, it must be in the = VK_IMAGE_LAYOUT_GENERAL layout.

  • Source images must have VK_FORMA= T_FEATURE_TRANSFER_SRC_BIT in their format features.

  • Destination images must have VK_= FORMAT_FEATURE_TRANSFER_DST_BIT in their format features.

  • Source images must have been created w= ith the VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage bit enabled and destinat= ion images must have been created with the VK_IMAGE_USAGE_TRANSFER_DST_BIT usage bit enabled.

  • Source buffers must have been created = with the VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage bit enabled and destina= tion buffers must have been created with the VK_BUFFER_USAGE_TRANSFER_DST_BIT usage bit enabled.

All copy commands are treated as =E2=80=9Ctransfer=E2=80=9D operations f= or the purposes of synchronization barriers.

18.2. Copying Data Between Buffers

To copy data between buffer objects, call:

void vkCmdCopyBuffer(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    srcBuffer,
    VkBuffer                                    dstBuffer,
    uint32_t                                    regionCount,
    const VkBufferCopy*                   =
      pRegions);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • srcBuffer is the source buffer.

  • dstBuffer is the destination buffer.

  • regionCount is the number of regions to copy.

  • pRegions is a pointer to an array of VkBuffer= Copy structures specifying the regions to copy.

Each region in pRegions is copied from the source buffer to= the same region of the destination buffer. srcBuffer and dstBuffer = can be the same buffer or alias the same memory, but the result is undefined if the copy regions overlap in memory.

Valid Usage
  • The srcOffset member of each element of pRegions = must be less than the size of srcBuffer

  • The dstOffset member of each element of pRegions = must be less than the size of dstBuffer

  • The size member of each element of pRegions must be less than or equal to the size of srcBuffer minus srcOffset

  • The size member of each element of pRegions must be less than or equal to the size of dstBuffer minus dstOffset

  • The union of the source regions, and the union of the destination regions, specified by the elements of pRegions, must not overlap in memory

  • srcBuffer must have been cre= ated with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag

  • If srcBuffer is non-sparse then it mu= st be bound completely and contiguously to a single VkDeviceMemory object

  • dstBuffer must have been cre= ated with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag

  • If dstBuffer is non-sparse then it mu= st be bound completely and contiguously to a single VkDeviceMemory object

  • If commandBuffer is an unprotected command buffer, then srcBuffer must not be a prot= ected buffer

  • If commandBuffer is an unprotected command buffer, then dstBuffer must not be a prot= ected buffer

  • If commandBuffer is a protected command buffer, then dstBuffer must not be an unp= rotected buffer

Valid Usage (Implicit)
  • comman= dBuffer must be a valid VkCo= mmandBuffer handle

  • srcBuffer<= /code> must be a valid VkBuffer handle

  • dstBuffer<= /code> must be a valid VkBuffer handle

  • pRegions must be a valid pointer to an array = of regionCount valid VkBufferCopy structures

  • comman= dBuffer must be in the recording state

  • The VkCo= mmandPool that commandBuffer was allocated from must support transfer, graphics, or compute oper= ations

  • This command must only be called outside of a render pass instance=

  • region= Count must be greater than 0=

  • Each of commandBu= ffer, dstBuffer, and srcBuffer must have been created, allocated, or retrieved from= the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Tra= nsfer
Graphics
Compute

Tra= nsfer

The VkBufferCopy structure is defined as:

typedef struct VkBufferCopy {
    VkDeviceSize    srcOffset;
    VkDeviceSize    dstOffset;
    VkDeviceSize    size;
} VkBufferCopy;
  • srcOffset is the starting offset in bytes from the start of srcBuffer.

  • dstOffset is the starting offset in bytes from the start of dstBuffer.

  • size is the number of bytes to copy.

Valid Usage
  • The size must be greater tha= n 0

18.3. Copying Data Between Images

vkCmdCopyImage performs image copies in a similar manner to= a host memcpy. It does not perform general-purpose conversions such as scaling, resizing, blending, color-space conversion, or format conversions. Rather, it simply copies raw image data. vkCmdCopyImage can copy betw= een images with different formats, provided the formats are compatible as defined below.

To copy data between image objects, call:

void vkCmdCopyImage(
    VkCommandBuffer                             commandBuffer,
    VkImage                                     srcImage,
    VkImageLayout                               srcImageLayout,
    VkImage                                     dstImage,
    VkImageLayout                               dstImageLayout,
    uint32_t                                    regionCount,
    const VkImageCopy*                    =
      pRegions);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • srcImage is the source image.

  • srcImageLayout is the current layout of the source image subresource.

  • dstImage is the destination image.

  • dstImageLayout is the current layout of the destination ima= ge subresource.

  • regionCount is the number of regions to copy.

  • pRegions is a pointer to an array of VkImageCo= py structures specifying the regions to copy.

Each region in pRegions is copied from the source image to = the same region of the destination image. srcImage and dstImage ca= n be the same image or alias the same memory.

The formats of srcImage and dstImage must be compatible. Formats are considered compatible if their element size is the same between both formats. For example, VK_FORMAT_R8G8B8A8_UNORM is compatible with VK_FORMAT_R32_UINT because both texels are 4 bytes in size. Depth/stencil formats must match exactly.=

If the format of srcImage or dstImage is a multi-planar = image format, regions of each plane to be copied mus= t be specified separately using the srcSubresource and dstSubresource membe= rs of the VkImageCopy structure. In this case, the aspectMask of the srcSubresource or dstSubresource that refers to the multi-planar image must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT. For the purposes of vkCmdCopyImage, each plane of a multi-plan= ar image is treated as having the format listed in Compatible formats of planes of multi-p= lanar formats for the plane identified by the aspectMask of the corresponding subresource. This applies both to VkFormat and to coordinates used in the = copy, which correspond to texels in the plane rather than how these texe= ls map to coordinates in the image as a whole.

Note

For example, the VK_IMAGE_ASPECT_PLANE_1_BIT plane of a VK_FORMAT_G8_B8R8_2PLANE_420_UNORM image is compatible with an= image of format VK_FORMAT_R8G8_UNORM and (less usefully) with the VK_IMAGE_ASPECT_PLANE_0_BIT plane of an image of format VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, as each = texel is 2 bytes in size.

vkCmdCopyImage allows copying between size-compatible compressed and uncompressed internal formats. Formats are size-compatible if the element size of the uncompressed format is equal to the element size (compressed texel block size) of the compresse= d format. Such a copy does not perform on-the-fly compression or decompression. When copying from an uncompressed format to a compressed format, each texel of uncompressed data of the source image is copied as a raw value to the corresponding compressed texel block of the destination image. When copying from a compressed format to an uncompressed format, each compressed texel block of the source image is copied as a raw value to the corresponding texel of uncompressed data in the destination image. Thus, for example, it is legal to copy between a 128-bit uncompressed forma= t and a compressed format which has a 128-bit sized compressed texel block representing 4=C3=974 texels (using 8 bits per texel), or between a 64-bit uncompressed format and a compressed format which has a 64-bit sized compressed texel block representing 4=C3=974 texels (using 4 bits per texel).

When copying between compressed and uncompressed formats the exten= t members represent the texel dimensions of the source image and not the destination. When copying from a compressed image to an uncompressed image the image texel dimensions written to the uncompressed image will be source extent divided by the compressed texel block dimensions. When copying from an uncompressed image to a compressed image the image texel dimensions written to the compressed image will be the source extent multiplied by the compressed texel block dimensions. In both cases the number of bytes read and the number of bytes written will be identical.

Copying to or from block-compressed images is typically done in multiple= s of the compressed texel block size. For this reason the extent must be a multiple of the compressed texel block dimension. There is one exception to this rule which is requi= red to handle compressed images created with dimensions that are not a multiple of the compressed texel block dimensions: if the srcImage is compressed, then:

  • If extent.width is not a multiple of the compressed texel b= lock width, then (extent.width + srcOffse= t.x) must equal the image subresource width.

  • If extent.height is not a multiple of the compressed texel = block height, then (extent.height + srcOff= set.y) must equal the image subresource height.

  • If extent.depth is not a multiple of the compressed texel b= lock depth, then (extent.depth + srcOffse= t.z) must equal the image subresource depth.

Similarly, if the dstImage is compressed, then:

  • If extent.width is not a multiple of the compressed texel b= lock width, then (extent.width + dstOffse= t.x) must equal the image subresource width.

  • If extent.height is not a multiple of the compressed texel = block height, then (extent.height + dstOff= set.y) must equal the image subresource height.

  • If extent.depth is not a multiple of the compressed texel b= lock depth, then (extent.depth + dstOffse= t.z) must equal the image subresource depth.

This allows the last compressed texel block of the image in each non-multiple dimension to be included as a source or destination of the copy.

vkCmdCopyImage can be use= d to copy image data between multisample images, but both images must have the sam= e number of samples.

Valid Usage
  • The source region specified by each element of pRegions must be a region that is contained within srcImage if the srcImage=E2=80=99s VkFormat is not a multi-planar format, and must be a region that is = contained within the plane being copied if the srcImage=E2=80=99s VkFormat is a m= ulti-planar format

  • The destination region specified by each element of pRegions <= strong class=3D"purple">must be a region that is contained within dstImage if the dstImage=E2=80=99s VkFormat is not a multi-planar format, and must be a region that is = contained within the plane being copied to if the dstImage=E2=80=99s VkFormat is = a multi-planar format

  • The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory

  • The format features of srcImage must contain = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT.

  • srcImage must have been crea= ted with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag

  • If srcImage is non-sparse then the image or disjoint = plane to be copied must be bound completely and conti= guously to a single VkDeviceMemory object

  • srcImageLayout must specify = the layout of the image subresources of srcImage specified in pRegions at the time thi= s command is executed on a VkDevice

  • srcImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR

  • The format features of dstImage must contain = VK_FORMAT_FEATURE_TRANSFER_DST_BIT.

  • dstImage must have been crea= ted with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag

  • If dstImage is non-sparse then the image or disjoint = plane that is the destination of the copy must be bo= und completely and contiguously to a single VkDeviceMemory object

  • dstImageLayout must specify = the layout of the image subresources of dstImage specified in pRegions at the time thi= s command is executed on a VkDevice

  • dstImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR

  • If the VkFormat of each of srcImage and ds= tImage is not a multi-planar format, the VkFormat of each of srcImage and dstImage must be compatible,= as defined below

  • In a copy to or from a plane of a multi-planar image, the VkFormat of the image and plane must be compatible according to the description of compatible planes for the plane being copied

  • When a copy is performed to or from an image with a multi-planar format, the aspectMask of the srcSubresource = and/or dstSubresource that refers to the multi-planar image must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT (with VK_IMAGE_ASPECT_PLANE_2_BIT valid only for a VkForma= t with three planes)

  • The sample count of srcImage and dstImage must match

  • If commandBuffer is an unprotected command buffer, then srcImage must not be a prote= cted image

  • If commandBuffer is an unprotected command buffer, then dstImage must not be a prote= cted image

  • If commandBuffer is a protected command buffer, then dstImage must not be an unpr= otected image

  • The srcSubresource.mipLevel member of each element of pRegions must be less than t= he mipLevels specified in VkImageCreateInfo when srcImage was cre= ated

  • The dstSubresource.mipLevel member of each element of pRegions must be less than t= he mipLevels specified in VkImageCreateInfo when dstImage was cre= ated

  • The srcSubresource.baseArrayLayer +=20 srcSubresource.layerCount of each element of pReg= ions must be less than or equal to the arrayLayers specified in VkImageCreateInfo when srcImage was cre= ated

  • The dstSubresource.baseArrayLayer +=20 dstSubresource.layerCount of each element of pReg= ions must be less than or equal to the arrayLayers specified in VkImageCreateInfo when dstImage was cre= ated

  • The srcOffset and extent members of each element = of pRegions must respect the im= age transfer granularity requirements of commandBuffer=E2=80=99s command pool=E2=80=99s queue family= , as described in VkQueueFamilyProperties

  • The dstOffset and extent members of each element = of pRegions must respect the im= age transfer granularity requirements of commandBuffer=E2=80=99s command pool=E2=80=99s queue family= , as described in VkQueueFamilyProperties

Valid Usage (Implicit)
  • command= Buffer must be a valid VkCom= mandBuffer handle

  • srcImage must be a valid VkImage = handle

  • srcIma= geLayout must be a valid VkImageLayout value

  • dstImage must be a valid VkImage = handle

  • dstIma= geLayout must be a valid VkImageLayout value

  • pRegions must be a valid pointer to an array o= f regionCount valid VkImageCopy structures

  • command= Buffer must be in the recording state

  • The VkCom= mandPool that commandBuffer was allocated from must support transfer, graphics, or compute opera= tions

  • This command must only be called outside of a render pass instance<= /p>

  • regionC= ount must be greater than 0<= /code>

  • Each of commandBuf= fer, dstImage, and srcImage must have been created, allocated, or retrieved from t= he same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Tra= nsfer
Graphics
Compute

Tra= nsfer

The VkImageCopy structure is defined as:

typedef struct VkImageCopy {
    VkImageSubresourceLayers    srcSubresource;
    VkOffset3D                  srcOffset;
    VkImageSubresourceLayers    dstSubresource;
    VkOffset3D                  dstOffset;
    VkExtent3D                  extent;
} VkImageCopy;
  • srcSubresource and dstSubresource are VkImageSubresourceLayers structures specifyin= g the image subresources of the images used for the source and destination image data, respectively.

  • srcOffset and dstOffset select the initial x, y, and z offsets in texels of the sub-regions of the source and destination image data.

  • extent is the size in texels of the image to copy in = width, height and depth.

For VK_IMAGE_TYPE_3D images, copies are performed slice by = slice starting with the z member of the srcOffset or dstOffset, and copying depth slices. For images with multiple layers, copies are performed layer by layer starting with the baseArrayLayer member of the srcSubres= ource or dstSubresource and copying layerCount layers. Image data can be copied between images w= ith different image types. If one image is VK_IMAGE_TYPE_3D and the other image is VK_IMAGE_TYPE_2D with multiple layers, then each slice is copi= ed to or from a different layer.

Copies involving a = multi-planar image format specify the region to be copied in terms of t= he plane to be copied, not the coordinates of the multi-planar image. This means that copies accessing the R/B planes of =E2=80=9C_422=E2=80=9D format images must fit the copied region within = half the width of the parent image, and that copies accessing the R/B planes of =E2=80=9C_420=E2=80=9D format images must fit the copied region within = half the width and height of the parent image.

Valid Usage
  • If neither the calling command=E2=80=99s srcImage nor the call= ing command=E2=80=99s dstImage has a multi-planar image format then the aspectMask member of srcSubres= ource and dstSubresource must matc= h

  • If the calling command=E2=80=99s srcImage has a VkFo= rmat with two planes then the srcSubresource aspectMask must be VK_IMAGE_ASPECT_PLANE_0_BIT or VK_IMAGE_ASPECT_PLANE_1_B= IT

  • If the calling command=E2=80=99s srcImage has a VkFo= rmat with three planes then the srcSubresource aspectMask must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT

  • If the calling command=E2=80=99s dstImage has a VkFo= rmat with two planes then the dstSubresource aspectMask must be VK_IMAGE_ASPECT_PLANE_0_BIT or VK_IMAGE_ASPECT_PLANE_1_B= IT

  • If the calling command=E2=80=99s dstImage has a VkFo= rmat with three planes then the dstSubresource aspectMask must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT

  • If the calling command=E2=80=99s srcImage has a multi-planar image format and the dstImage does not have a multi-planar image format, the dstSubresource aspectMask must be VK_IMAGE_ASPECT_COLOR_BIT

  • If the calling command=E2=80=99s dstImage has a multi-planar image format and the srcImage does not have a multi-planar image format, the srcSubresource aspectMask must be VK_IMAGE_ASPECT_COLOR_BIT

  • The number of slices of the extent (for 3D) or layers of the srcSubresource (for non-3D) must match the number of slices of the extent (for 3D) or layers of the dstSubresource (for non-3D)

  • If either of the calling command=E2=80=99s srcImage or d= stImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of the corr= esponding subresource must be 0 and 1, respectively

  • The aspectMask member of srcSubresource must specify aspects present in the calling command=E2=80=99s srcImage

  • The aspectMask member of dstSubresource must specify aspects present in the calling command=E2=80=99s dstImage

  • srcOffset.x and (extent.width = +=20 srcOffset.x) must bot= h be greater than or equal to 0 and less than or equal to the source image subresource width

  • srcOffset.y and (extent.height= +=20 srcOffset.y) must bot= h be greater than or equal to 0 and less than or equal to the source image subresource height

  • If the calling command=E2=80=99s srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be = 1.

  • srcOffset.z and (extent.depth = +=20 srcOffset.z) must bot= h be greater than or equal to 0 and less than or equal to the source image subresource depth

  • If the calling command=E2=80=99s srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.z must be 0 and extent.depth must be 1= .

  • If the calling command=E2=80=99s dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.z must be 0 and extent.depth must be 1= .

  • If the calling command=E2=80=99s srcImage is of type VK_IMAGE_TYPE_2D, then srcOffset.z must be 0.

  • If the calling command=E2=80=99s dstImage is of type VK_IMAGE_TYPE_2D, then dstOffset.z must be 0.

  • If both srcImage and dstImage are of type VK_IMAGE_TYPE_2D then then extent.depth must be 1.

  • If the calling command=E2=80=99s srcImage is of type VK_IMAGE_TYPE_2D, and the dstImage is of type VK_IMAGE_TYPE_3D, then extent.depth must equal to the layerCount member of srcSubresource.

  • If the calling command=E2=80=99s dstImage is of type VK_IMAGE_TYPE_2D, and the srcImage is of type VK_IMAGE_TYPE_3D, then extent.depth must equal to the layerCount member of dstSubresource.

  • dstOffset.x and (extent.width = +=20 dstOffset.x) must bot= h be greater than or equal to 0 and less than or equal to the destination image subresource width

  • dstOffset.y and (extent.height= +=20 dstOffset.y) must bot= h be greater than or equal to 0 and less than or equal to the destination image subresource height

  • If the calling command=E2=80=99s dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be = 1.

  • dstOffset.z and (extent.depth = +=20 dstOffset.z) must bot= h be greater than or equal to 0 and less than or equal to the destination image subresource depth

  • If the calling command=E2=80=99s srcImage is a compressed imag= e, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, all members of srcOffset must be a multiple of the corresponding dimensions of the compressed texel block

  • If the calling command=E2=80=99s srcImage is a compressed imag= e, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, extent.width must be a multi= ple of the compressed texel block width or (extent.width + srcOffset.x= ) must equal the source image subresource width

  • If the calling command=E2=80=99s srcImage is a compressed imag= e, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, extent.height must be a mult= iple of the compressed texel block height or (extent.height + srcOffset= .y) must equal the source image subresource height

  • If the calling command=E2=80=99s srcImage is a compressed imag= e, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, extent.depth must be a multi= ple of the compressed texel block depth or (extent.depth + srcOffset.z= ) must equal the source image subresource depth

  • If the calling command=E2=80=99s dstImage is a compressed form= at image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, all members of dstOffset must be a multiple of the corresponding dimensions of the compressed texel block

  • If the calling command=E2=80=99s dstImage is a compressed form= at image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, extent.width must be a multi= ple of the compressed texel block width or (extent.width + dstOffset.x= ) must equal the destination image subresource width

  • If the calling command=E2=80=99s dstImage is a compressed form= at image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, extent.height must be a mult= iple of the compressed texel block height or (extent.height + dstOffset= .y) must equal the destination image subresource height

  • If the calling command=E2=80=99s dstImage is a compressed form= at image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, extent.depth must be a multi= ple of the compressed texel block depth or (extent.depth + dstOffset.z= ) must equal the destination image subresource depth

Valid Usage (Implicit)
  • srcSubres= ource must be a valid VkImag= eSubresourceLayers structure

  • dstSubres= ource must be a valid VkImag= eSubresourceLayers structure

The VkImageSubresourceLayers structure is defined as:

typedef struct VkImageSubresour=
ceLayers {
    VkImageAspectFlags    aspectMask;
    uint32_t              mipLevel;
    uint32_t              baseArrayLayer;
    uint32_t              layerCount;
} VkImageSubresourceLayers;
  • aspectMask is a combination of VkIma= geAspectFlagBits, selecting the color, depth and/or stencil aspects to be copied.

  • mipLevel is the mipmap level to copy from.

  • baseArrayLayer and layerCount are the starting= layer and number of layers to copy.

Valid Usage
  • If aspectMask contains VK_IMAGE_ASPECT_COLOR_BIT,= it must not contain either of VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT

  • aspectMask must not contain = VK_IMAGE_ASPECT_METADATA_BIT

  • layerCount must be greater t= han 0

Valid Usage (Implicit)

18.4. Copying Data Between Buffers and Ima= ges

To copy data from a buffer object to an image object, call:

void vkCmdCopyBufferToImage(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    srcBuffer,
    VkImage                                     dstImage,
    VkImageLayout                               dstImageLayout,
    uint32_t                                    regionCount,
    const VkBufferImageCopy*              =
      pRegions);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • srcBuffer is the source buffer.

  • dstImage is the destination image.

  • dstImageLayout is the layout of the destination image subre= sources for the copy.

  • regionCount is the number of regions to copy.

  • pRegions is a pointer to an array of VkB= ufferImageCopy structures specifying the regions to copy.

Each region in pRegions is copied from the specified region= of the source buffer to the specified region of the destination image.

If the format of dstImage is a multi-planar image format), regions of each plane to be a target of a copy must be specified separately using the pRegions member of the VkBufferImageCopy structure. In this case, the aspectMask of imageSubresource = must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT. For the purposes of vkCmdCopyBufferToImage, each plane of a multi-planar image is treated as having the format listed in Compatible formats of planes of multi-p= lanar formats for the plane identified by the aspectMask of the corresponding subresource. This applies both to VkFormat and to coordinates used in the = copy, which correspond to texels in the plane rather than how these texe= ls map to coordinates in the image as a whole.

Valid Usage
  • srcBuffer must be large enou= gh to contain all buffer locations that are accessed according to Buffer and Image Addressing, for each element of pRegions

  • The image region specified by each element of pRegions must be a region that is contained within dstImage if the dstImage=E2=80=99s VkFormat is not a multi-planar format, and must be a region that is = contained within the plane being copied to if the dstImage=E2=80=99s VkFormat is = a multi-planar format

  • The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory

  • srcBuffer must have been cre= ated with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag

  • The format features of dstImage must contain = VK_FORMAT_FEATURE_TRANSFER_DST_BIT.

  • If srcBuffer is non-sparse then it mu= st be bound completely and contiguously to a single VkDeviceMemory object

  • dstImage must have been crea= ted with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag

  • If dstImage is non-sparse then it mus= t be bound completely and contiguously to a single VkDeviceMemory object

  • dstImage must have a sample = count equal to VK_SAMPLE_COUNT_1_BIT

  • dstImageLayout must specify = the layout of the image subresources of dstImage specified in pRegions at the time thi= s command is executed on a VkDevice

  • dstImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR

  • If commandBuffer is an unprotected command buffer, then srcBuffer must not be a prot= ected buffer

  • If commandBuffer is an unprotected command buffer, then dstImage must not be a prote= cted image

  • If commandBuffer is a protected command buffer, then dstImage must not be an unpr= otected image

  • The imageSubresource.mipLevel member of each element of pRegions must be less than t= he mipLevels specified in VkImageCreateInfo when dstImage was cre= ated

  • The imageSubresource.baseArrayLayer +=20 imageSubresource.layerCount of each element of pR= egions must be less than or equal to the a= rrayLayers specified in VkImageCreateInfo when dstImage was cre= ated

  • The imageOffset and imageExtent members of each e= lement of pRegions must respect the im= age transfer granularity requirements of commandBuffer=E2=80=99s command pool=E2=80=99s queue family= , as described in VkQueueFamilyProperties

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • src= Buffer must be a valid VkBuf= fer handle

  • dstI= mage must be a valid VkImage= handle

  • dstImageLayout must be a valid <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kImageLayout">VkImageLayout value

  • pReg= ions must be a valid pointer to an= array of regionCount valid VkBufferImageCopy str= uctures

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from = must support transfer, graphics, or compu= te operations

  • This command must only be called outside of a render pass i= nstance

  • regionCount must be greater than = 0

  • Each of co= mmandBuffer, dstImage, and srcBuffer must have been created, allocated, or retrieve= d from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Tra= nsfer
Graphics
Compute

Tra= nsfer

To copy data from an image object to a buffer object, call:

void vkCmdCopyImageToBuffer(
    VkCommandBuffer                             commandBuffer,
    VkImage                                     srcImage,
    VkImageLayout                               srcImageLayout,
    VkBuffer                                    dstBuffer,
    uint32_t                                    regionCount,
    const VkBufferImageCopy*              =
      pRegions);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • srcImage is the source image.

  • srcImageLayout is the layout of the source image subresourc= es for the copy.

  • dstBuffer is the destination buffer.

  • regionCount is the number of regions to copy.

  • pRegions is a pointer to an array of VkB= ufferImageCopy structures specifying the regions to copy.

Each region in pRegions is copied from the specified region= of the source image to the specified region of the destination buffer.

If the VkFormat of srcImage is a multi-planar image format, regions of each plane to be a source of a copy must be specified separately using the pRegions member of the VkBufferImageCopy structure. In this case, the aspectMask of imageSubresource = must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT= , or VK_IMAGE_ASPECT_PLANE_2_BIT. For the purposes of vkCmdCopyBufferToImage, each plane of a multi-planar image is treated as having the format listed in Compatible formats of planes of multi-p= lanar formats for the plane identified by the aspectMask of the corresponding subresource. This applies both to VkFormat and to coordinates used in the = copy, which correspond to texels in the plane rather than how these texe= ls map to coordinates in the image as a whole.

Valid Usage
  • The image region specified by each element of pRegions must be a region that is contained within srcImage if the srcImage=E2=80=99s VkFormat is not a multi-planar format, and must be a region that is = contained within the plane being copied if the srcImage=E2=80=99s VkFormat is a m= ulti-planar format

  • dstBuffer must be large enou= gh to contain all buffer locations that are accessed according to Buffer and Image Addressing, for each element of pRegions

  • The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory

  • The format features of srcImage must contain = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT.

  • srcImage must have been crea= ted with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag

  • If srcImage is non-sparse then it mus= t be bound completely and contiguously to a single VkDeviceMemory object

  • srcImage must have a sample = count equal to VK_SAMPLE_COUNT_1_BIT

  • srcImageLayout must specify = the layout of the image subresources of srcImage specified in pRegions at the time thi= s command is executed on a VkDevice

  • srcImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

  • dstBuffer must have been cre= ated with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag

  • If dstBuffer is non-sparse then it mu= st be bound completely and contiguously to a single VkDeviceMemory object

  • If commandBuffer is an unprotected command buffer, then srcImage must not be a prote= cted image

  • If commandBuffer is an unprotected command buffer, then dstBuffer must not be a prot= ected buffer

  • If commandBuffer is a protected command buffer, then dstBuffer must not be an unp= rotected buffer

  • The imageSubresource.mipLevel member of each element of pRegions must be less than t= he mipLevels specified in VkImageCreateInfo when srcImage was cre= ated

  • The imageSubresource.baseArrayLayer +=20 imageSubresource.layerCount of each element of pR= egions must be less than or equal to the a= rrayLayers specified in VkImageCreateInfo when srcImage was cre= ated

  • The imageOffset and imageExtent members of each e= lement of pRegions must respect the im= age transfer granularity requirements of commandBuffer=E2=80=99s command pool=E2=80=99s queue family= , as described in VkQueueFamilyProperties

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • srcI= mage must be a valid VkImage= handle

  • srcImageLayout must be a valid <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kImageLayout">VkImageLayout value

  • dst= Buffer must be a valid VkBuf= fer handle

  • pReg= ions must be a valid pointer to an= array of regionCount valid VkBufferImageCopy str= uctures

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from = must support transfer, graphics, or compu= te operations

  • This command must only be called outside of a render pass i= nstance

  • regionCount must be greater than = 0

  • Each of co= mmandBuffer, dstBuffer, and srcImage must have been created, allocated, or retrieve= d from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Tra= nsfer
Graphics
Compute

Tra= nsfer

For both vkCmdCopyBufferToImage and vkCmdCopyImageToBuffer, each element of pRegions is a structure defined as:

typedef struct VkBufferImageCop=
y {
    VkDeviceSize                bufferOffset;
    uint32_t                    bufferRowLength;
    uint32_t                    bufferImageHeight;
    VkImageSubresourceLayers    imageSubresource;
    VkOffset3D                  imageOffset;
    VkExtent3D                  imageExtent;
} VkBufferImageCopy;
  • bufferOffset is the offset in bytes from the start of the b= uffer object where the image data is copied from or to.

  • bufferRowLength and bufferImageHeight specify = the data in buffer memory as a subregion of a larger two- or three-dimensional image, and control the addressing calculations of data in buffer memory. If either of these values is zero, that aspect of the buffer memory is considered to be tightly packed according to the imageExtent.<= /p>

  • imageSubresource is a VkImageSubr= esourceLayers used to specify the specific image subresources of the image used for the source or destination image data.

  • imageOffset selects the initial x, y, z offsets in texels of the sub-region of the source or destination image data.

  • imageExtent is the size in texels of the image to copy in width, height and depth.

When copying to or from a depth or stencil aspect, the data in buffer me= mory uses a layout that is a (mostly) tightly packed representation of the depth or stencil data. Specifically:

  • data copied to or from the stencil aspect of any depth/stencil format is tightly packed with one VK_FORMAT_S8_UINT value per texel.

  • data copied to or from the depth aspect of a VK_FORMAT_D16_UNORM or VK_FORMAT_D16_UNORM_S8_UINT format is tightly packed with o= ne VK_FORMAT_D16_UNORM value per texel.

  • data copied to or from the depth aspect of a VK_FORMAT_D32_SFLOAT<= /code> or VK_FORMAT_D32_SFLOAT_S8_UINT format is tightly packed with = one VK_FORMAT_D32_SFLOAT value per texel.

  • data copied to or from the depth aspect of a VK_FORMAT_X8_D24_UNORM_PACK32 or VK_FORMAT_D24_UNORM_S8_= UINT format is packed with one 32-bit word per texel with the D24 value in the LSBs of the word, and undefined values in the eight MSBs.

Note

To copy both the depth and stencil aspects of a depth/stencil format, tw= o entries in pRegions can be u= sed, where one specifies the depth aspect in imageSubresource, and the other specifies the stencil aspec= t.

Because depth or stencil aspect buffer to image copies may require format conversions on some implementations, they are not supported on queues that do not support graphics. When copying to a depth aspect, the data in buffer memory must be in the the range [0,1] or undefined results occur.

Copies are done layer by layer starting with image layer baseArrayLayer member of imageSubresource. layerCount layers are copied from the source image or to the destination image.

Valid Usage
  • If the calling command=E2=80=99s VkImage parameter=E2=80=99s f= ormat is not a depth/stencil format or a multi-planar format, then bufferOffset must be a multiple of the format=E2=80=99s element size

  • If the calling command=E2=80=99s VkImage parameter=E2=80=99s f= ormat is a multi-planar format, then bufferOffset must be a multiple of the element size of the compatible format for the format and the aspectMask of the imageSubresource as defined in Compatible formats of planes of multi-p= lanar formats

  • bufferOffset must be a multi= ple of 4

  • bufferRowLength must be 0, or greater than or equal to the width member of imageExtent

  • bufferImageHeight must be 0, or greater than or equal to the height member of imageExtent

  • imageOffset.x and (imageExtent.width<= /code> +=20 imageOffset.x) must b= oth be greater than or equal to 0 and less than or equal to the image subresource width where this refers to the width of the plane of the image involved = in the copy in the case of a multi-planar format

  • imageOffset.y and (imageExtent.height +=20 imageOffset.y) must b= oth be greater than or equal to 0 and less than or equal to the image subresource height where this refers to the height of the plane of the image involved= in the copy in the case of a multi-planar format

  • If the calling command=E2=80=99s srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D, then imageOffset.y must be 0 and imageExtent.height must be <= code>1.

  • imageOffset.z and (imageExtent.depth +=20 imageOffset.z) must b= oth be greater than or equal to 0 and less than or equal to the image subresource depth

  • If the calling command=E2=80=99s srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then imageOffset.z must be = 0 and imageExtent.depth must be 1

  • If the calling command=E2=80=99s VkImage parameter is a compre= ssed image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, bufferRowLength must be a mu= ltiple of the compressed texel block width

  • If the calling command=E2=80=99s VkImage parameter is a compre= ssed image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, bufferImageHeight must be a = multiple of the compressed texel block height

  • If the calling command=E2=80=99s VkImage parameter is a compre= ssed image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, all members of imageOffset must be a multiple of the corresponding dimensions of the compressed texel block

  • If the calling command=E2=80=99s VkImage parameter is a compre= ssed image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, bufferOffset must be a multi= ple of the compressed texel block size in bytes

  • If the calling command=E2=80=99s VkImage parameter is a compre= ssed image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, imageExtent.width must be a = multiple of the compressed texel block width or (imageExtent.width +=20 imageOffset.x) must e= qual the image subresource width

  • If the calling command=E2=80=99s VkImage parameter is a compre= ssed image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, imageExtent.height must be a= multiple of the compressed texel block height or (imageExtent.height +=20 imageOffset.y) must e= qual the image subresource height

  • If the calling command=E2=80=99s VkImage parameter is a compre= ssed image, or a single-plane, =E2=80=9C_422=E2=80=9D image forma= t, imageExtent.depth must be a = multiple of the compressed texel block depth or (imageExtent.depth +=20 imageOffset.z) must e= qual the image subresource depth

  • The aspectMask member of imageSubresource must specify aspects present in the calling command=E2=80=99s VkImage param= eter

  • If the calling command=E2=80=99s VkImage parameter=E2=80=99s f= ormat is a multi-planar format, then the aspectMask member of imageSubresour= ce must be VK_IMAGE_ASPECT_PLANE_0_BIT= , VK_IMAGE_ASPECT_PLANE_1_BIT, or VK_IMAGE_ASPECT_PLANE_2_= BIT (with VK_IMAGE_ASPECT_PLANE_2_BIT valid only for image formats with three planes)

  • The aspectMask member of imageSubresource must only have a single bit set

  • If the calling command=E2=80=99s VkImage parameter is of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and la= yerCount members of imageSubresource must be 0 and 1, respectively

  • When copying to the depth aspect of an image subresource, the data in the source buffer must be in the range [0,1]

Valid Usage (Implicit)
  • i= mageSubresource must be a valid VkImageSubresourceLayers structure

18.4.1. Buffer and Image Addres= sing

Pseudocode for image/buffer addressing is:

rowLength =3D region=
->bufferRowLength;
if (rowLength =3D=3D 0)
    rowLength =3D region->imageExtent.width;

imageHeight =3D region->bufferImageHeight;
if (imageHeight =3D=3D 0)
    imageHeight =3D region->imageExtent.height;

elementSize =3D <element size of the format of the src/dstImage>;

address of (x,y,z) =3D region->bufferOffset + (((z * imageHeight) + y) *=
 rowLength + x) * elementSize;

where x,y,z range from (0,0,0) to region->imageExtent.=
{width,height,depth}.

Note that imageOffset does not affect addressing calculatio= ns for buffer memory. Instead, bufferOffset can be= used to select the starting address in buffer memory.

For block-compression formats, all parameters are still specified in tex= els rather than compressed texel blocks, but the addressing math operates on whole compressed texel blocks. Pseudocode for compressed copy addressing is:

rowLength =3D region=
->bufferRowLength;
if (rowLength =3D=3D 0)
    rowLength =3D region->imageExtent.width;

imageHeight =3D region->bufferImageHeight;
if (imageHeight =3D=3D 0)
    imageHeight =3D region->imageExtent.height;

compressedTexelBlockSizeInBytes =3D <compressed texel block size taken f=
rom the src/dstImage>;
rowLength /=3D compressedTexelBlockWidth;
imageHeight /=3D compressedTexelBlockHeight;

address of (x,y,z) =3D region->bufferOffset + (((z * imageHeight) + y) *=
 rowLength + x) * compressedTexelBlockSizeInBytes;

where x,y,z range from (0,0,0) to region->imageExtent.=
{width/compressedTexelBlockWidth,height/compressedTexelBlockHeight,depth/co=
mpressedTexelBlockDepth}.

Copying to or from block-compressed images is typically done in multiple= s of the compressed texel block size. For this reason the imageExtent must<= /strong> be a multiple of the compressed texel block dimension. There is one exception to this rule which is requi= red to handle compressed images created with dimensions that are not a multiple of the compressed texel block dimensions:

  • If imageExtent.width is not a multiple of the compressed te= xel block width, then (imageExtent.width +=20 imageOffset.x) must e= qual the image subresource width.

  • If imageExtent.height is not a multiple of the compressed t= exel block height, then (imageExtent.height +=20 imageOffset.y) must e= qual the image subresource height.

  • If imageExtent.depth is not a multiple of the compressed te= xel block depth, then (imageExtent.depth +=20 imageOffset.z) must e= qual the image subresource depth.

This allows the last compressed texel block of the image in each non-multiple dimension to be included as a source or destination of the copy.

18.5. Image Copies with Scaling

To copy regions of a source image into a destination image, potentially performing format conversion, arbitrary scaling, and filtering, call:

void vkCmdBlitImage(
    VkCommandBuffer                             commandBuffer,
    VkImage                                     srcImage,
    VkImageLayout                               srcImageLayout,
    VkImage                                     dstImage,
    VkImageLayout                               dstImageLayout,
    uint32_t                                    regionCount,
    const VkImageBlit*                    =
      pRegions,
    VkFilter                                    filter);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • srcImage is the source image.

  • srcImageLayout is the layout of the source image subresourc= es for the blit.

  • dstImage is the destination image.

  • dstImageLayout is the layout of the destination image subre= sources for the blit.

  • regionCount is the number of regions to blit.

  • pRegions is a pointer to an array of VkImageBl= it structures specifying the regions to blit.

  • filter is a VkFilter specifying the filter to= apply if the blits require scaling.

vkCmdBlitImage must not b= e used for multisampled source or destination images. Use vkCmdResolveImage for this purpose.

As the sizes of the source and destination extents can differ in any dimension, texels in the source extent are scaled and filtered to the destination extent. Scaling occurs via the following operations:

  • For each destination texel, the integer coordinate of that texel is converted to an unnormalized texture coordinate, using the effective inverse of the equations described in unnormalized to integer conversion:

    ubase =3D i + =C2=BD

    vbase =3D j + =C2=BD

    wbase =3D k + =C2=BD

  • These base coordinates are then offset by the first destination offset:

    uoffset =3D ubase - xdst0<= /sub>

    voffset =3D vbase - ydst0<= /sub>

    woffset =3D wbase - zdst0<= /sub>

    aoffset =3D a - baseArrayCountdst

  • The scale is determined from the source and destination regions, and applied to the offset coordinates:

    scale_u =3D (xsrc1 - xsrc0) / (= xdst1 - xdst0)

    scale_v =3D (ysrc1 - ysrc0) / (= ydst1 - ydst0)

    scale_w =3D (zsrc1 - zsrc0) / (= zdst1 - zdst0)

    uscaled =3D uoffset * scaleu

    vscaled =3D voffset * scalev

    wscaled =3D woffset * scalew

  • Finally the source offset is added to the scaled coordinates, to determine the final unnormalized coordinates used to sample from srcImage:

    u =3D uscaled + xsrc0

    v =3D vscaled + ysrc0

    w =3D wscaled + zsrc0

    q =3D mipLevel

    a =3D aoffset + baseArrayCountsrc

These coordinates are used to sample from the source image, as described= in Image Operations chapter, with the filter mode equal to that of filter, a mipmap mode of VK_SAMPLER_MIPMAP_MODE_NEARE= ST and an address mode of VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE. Implementations must clamp at the edge of= the source image, and may additionally clamp to the edge of the source region.

Note

Due to allowable rounding errors in the generation of the source texture coordinates, it is not always possible to guarantee exactly which source texels will be sampled for a given blit. As rounding errors are implementation dependent, the exact results of a blitting operation are also implementation dependent.

Blits are done layer by layer starting with the baseArrayLayer member of srcSubresource for the source and dstSubresource for the destination. layerCount layers are blitted to the destination image.

3D textures are blitted slice by slice. Slices in the source region bounded by srcOffsets[0].z and srcOffsets[1].z are copied to slices in the desti= nation region bounded by dstOffsets[0].z and dstOffsets[1].z. For each destination slice, a source z coordinate is linea= rly interpolated between srcOffsets[0].z and srcOffsets[1].z. If the filter parameter is VK_FILTER_LINEAR then = the value sampled from the source image is taken by doing linear filtering using the interpolated z coordinate. If filter parameter is VK_FILTER_NEAREST then val= ue sampled from the source image is taken from the single nearest slice (with undefined rounding mode).

The following filtering and conversion rules apply:

  • Integer formats can only be converted = to other integer formats with the same signedness.

  • No format conversion is supported between depth/stencil images. The formats must match.

  • Format conversions on unorm, snorm, unscaled and packed float formats of the copied aspect of the image are performed by first converting the pixels to float values.

  • For sRGB source formats, nonlinear RGB values are converted to linear representation prior to filtering.

  • After filtering, the float values are first clamped and then cast to the destination image format. In case of sRGB destination format, linear RGB values are converted to nonlinear representation before writing the pixel to the image.

Signed and unsigned integers are converted by first clamping to the representable range of the destination format, then casting the value.

Valid Usage
  • The source region specified by each element of pRegions must be a region that is contained within srcImage

  • The destination region specified by each element of pRegions <= strong class=3D"purple">must be a region that is contained within dstImage

  • The union of all destination regions, specified by the elements of pRegions, must not overlap i= n memory with any texel that may be sampled during the blit operation

  • The format features of srcImage must contain = VK_FORMAT_FEATURE_BLIT_SRC_BIT.

  • srcImage must not use a form= at listed in Formats requiring samp= ler Y=E2=80=99CBCR conversion for VK_IMAGE_ASPE= CT_COLOR_BIT image views

  • srcImage must have been crea= ted with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag

  • If srcImage is non-sparse then it mus= t be bound completely and contiguously to a single VkDeviceMemory object

  • srcImageLayout must specify = the layout of the image subresources of srcImage specified in pRegions at the time thi= s command is executed on a VkDevice

  • srcImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

  • The format features of dstImage must contain = VK_FORMAT_FEATURE_BLIT_DST_BIT.

  • dstImage must not use a form= at listed in Formats requiring samp= ler Y=E2=80=99CBCR conversion for VK_IMAGE_ASPE= CT_COLOR_BIT image views

  • dstImage must have been crea= ted with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag

  • If dstImage is non-sparse then it mus= t be bound completely and contiguously to a single VkDeviceMemory object

  • dstImageLayout must specify = the layout of the image subresources of dstImage specified in pRegions at the time thi= s command is executed on a VkDevice

  • dstImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

  • The sample count of srcImage and dstImage must both be equal to VK_SAMPLE_COUNT_1_BIT

  • If either of srcImage or dstImage was created wit= h a signed integer VkFormat, the other must also have been created with a signed integer VkFormat

  • If either of srcImage or dstImage was created wit= h an unsigned integer VkFormat, the other must also have been created with an unsigned integer VkFormat

  • If either of srcImage or dstImage was created wit= h a depth/stencil format, the other must have= exactly the same format

  • If srcImage was created with a depth/stencil format, fil= ter must be VK_FILTER_NEAREST

  • srcImage must have been crea= ted with a samples value of VK_SAMPLE_COUNT_1_BIT

  • dstImage must have been crea= ted with a samples value of VK_SAMPLE_COUNT_1_BIT

  • If filter is VK_FILTER_LINEAR, then the format features of srcImage must contain VK_FORMAT_FEATURE_SAMP= LED_IMAGE_FILTER_LINEAR_BIT.

  • If filter is VK_FILTER_CUBIC_IMG, then the format features of srcImage must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • If filter is VK_FILTER_CUBIC_IMG, srcImage<= /code> must have a VkImageType of VK_IMAGE_TYPE_2D

  • If commandBuffer is an unprotected command buffer, then srcImage must not be a prote= cted image

  • If commandBuffer is an unprotected command buffer, then dstImage must not be a prote= cted image

  • If commandBuffer is a protected command buffer, then dstImage must not be an unpr= otected image

  • The srcSubresource.mipLevel member of each element of pRegions must be less than t= he mipLevels specified in VkImageCreateInfo when srcImage was cre= ated

  • The dstSubresource.mipLevel member of each element of pRegions must be less than t= he mipLevels specified in VkImageCreateInfo when dstImage was cre= ated

  • The srcSubresource.baseArrayLayer +=20 srcSubresource.layerCount of each element of pReg= ions must be less than or equal to the arrayLayers specified in VkImageCreateInfo when srcImage was cre= ated

  • The dstSubresource.baseArrayLayer +=20 dstSubresource.layerCount of each element of pReg= ions must be less than or equal to the arrayLayers specified in VkImageCreateInfo when dstImage was cre= ated

Valid Usage (Implicit)
  • command= Buffer must be a valid VkCom= mandBuffer handle

  • srcImage must be a valid VkImage = handle

  • srcIma= geLayout must be a valid VkImageLayout value

  • dstImage must be a valid VkImage = handle

  • dstIma= geLayout must be a valid VkImageLayout value

  • pRegions must be a valid pointer to an array o= f regionCount valid VkImageBlit structures

  • filter = must be a valid VkFilter va= lue

  • command= Buffer must be in the recording state

  • The VkCom= mandPool that commandBuffer was allocated from must support graphics operations

  • This command must only be called outside of a render pass instance<= /p>

  • regionC= ount must be greater than 0<= /code>

  • Each of commandBuf= fer, dstImage, and srcImage must have been created, allocated, or retrieved from t= he same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Gra= phics

Tra= nsfer

The VkImageBlit structure is defined as:

typedef struct VkImageBlit {
    VkImageSubresourceLayers    srcSubresource;
    VkOffset3D                  srcOffsets[2=
];
    VkImageSubresourceLayers    dstSubresource;
    VkOffset3D                  dstOffsets[2=
];
} VkImageBlit;
  • srcSubresource is the subresource to blit from.

  • srcOffsets is an array of two VkOffset3D st= ructures specifying the bounds of the source region within srcSubresource.

  • dstSubresource is the subresource to blit into.

  • dstOffsets is an array of two VkOffset3D st= ructures specifying the bounds of the destination region within dstSubresource.

For each element of the pRegions array, a blit operation is= performed the specified source and destination regions.

Valid Usage
  • The aspectMask member of srcSubresource and dstSubresource must match

  • The layerCount member of srcSubresource and dstSubresource must match

  • If either of the calling command=E2=80=99s srcImage or d= stImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively

  • The aspectMask member of srcSubresource must specify aspects present in the calling command=E2=80=99s srcImage

  • The aspectMask member of dstSubresource must specify aspects present in the calling command=E2=80=99s dstImage

  • srcOffset[0].x and srcOffset[1].x must both be greater than or equal to 0 and less than or equal to the sourc= e image subresource width

  • srcOffset[0].y and srcOffset[1].y must both be greater than or equal to 0 and less than or equal to the sourc= e image subresource height

  • If the calling command=E2=80=99s srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset[0].y must be 0 and srcOffset[1].y must be 1.

  • srcOffset[0].z and srcOffset[1].z must both be greater than or equal to 0 and less than or equal to the sourc= e image subresource depth

  • If the calling command=E2=80=99s srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset[0].z must be 0 and srcOffset[1].z must be 1.

  • dstOffset[0].x and dstOffset[1].x must both be greater than or equal to 0 and less than or equal to the desti= nation image subresource width

  • dstOffset[0].y and dstOffset[1].y must both be greater than or equal to 0 and less than or equal to the desti= nation image subresource height

  • If the calling command=E2=80=99s dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset[0].y must be 0 and dstOffset[1].y must be 1.

  • dstOffset[0].z and dstOffset[1].z must both be greater than or equal to 0 and less than or equal to the desti= nation image subresource depth

  • If the calling command=E2=80=99s dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset[0].z must be 0 and dstOffset[1].z must be 1.

Valid Usage (Implicit)
  • srcSubres= ource must be a valid VkImag= eSubresourceLayers structure

  • dstSubres= ource must be a valid VkImag= eSubresourceLayers structure

18.6. Resolving Multisample Images

To resolve a multisample image to a non-multisample image, call:

void vkCmdResolveImage(
    VkCommandBuffer                             commandBuffer,
    VkImage                                     srcImage,
    VkImageLayout                               srcImageLayout,
    VkImage                                     dstImage,
    VkImageLayout                               dstImageLayout,
    uint32_t                                    regionCount,
    const VkImageResolve*                 =
      pRegions);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • srcImage is the source image.

  • srcImageLayout is the layout of the source image subresourc= es for the resolve.

  • dstImage is the destination image.

  • dstImageLayout is the layout of the destination image subre= sources for the resolve.

  • regionCount is the number of regions to resolve.

  • pRegions is a pointer to an array of VkImag= eResolve structures specifying the regions to resolve.

During the resolve the samples corresponding to each pixel location in t= he source are converted to a single sample before being written to the destination. If the source formats are floating-point or normalized types, the sample values for each pixel are resolved in an implementation-dependent manner. If the source formats are integer types, a single sample=E2=80=99s value is= selected for each pixel.

srcOffset and dstOffset select the initial x, y, and z offsets in texels of the sub-regions of the source and desti= nation image data. extent is the size in texels of the source image to resolve in width, height and depth.

Resolves are done layer by layer starting with baseArrayLayer member of srcSubresource for the source and dstSubresource for the destination. layerCount layers are resolved to the destination image.

Valid Usage
  • The source region specified by each element of pRegions must be a region that is contained within srcImage

  • The destination region specified by each element of pRegions <= strong class=3D"purple">must be a region that is contained within dstImage

  • The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory

  • If srcImage is non-sparse then it mus= t be bound completely and contiguously to a single VkDeviceMemory object

  • srcImage must have a sample = count equal to any valid sample count value other than VK_SAMPLE_COUNT_1_BIT

  • If dstImage is non-sparse then it mus= t be bound completely and contiguously to a single VkDeviceMemory object

  • dstImage must have a sample = count equal to VK_SAMPLE_COUNT_1_BIT

  • srcImageLayout must specify = the layout of the image subresources of srcImage specified in pRegions at the time thi= s command is executed on a VkDevice

  • srcImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

  • dstImageLayout must specify = the layout of the image subresources of dstImage specified in pRegions at the time thi= s command is executed on a VkDevice

  • dstImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL

  • The format features of dstImage must contain VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT.

  • srcImage and dstImage mu= st have been created with the same image format

  • If commandBuffer is an unprotected command buffer, then srcImage must not be a prote= cted image

  • If commandBuffer is an unprotected command buffer, then dstImage must not be a prote= cted image

  • If commandBuffer is a protected command buffer, then dstImage must not be an unpr= otected image

  • The srcSubresource.mipLevel member of each element of pRegions must be less than t= he mipLevels specified in VkImageCreateInfo when srcImage was cre= ated

  • The dstSubresource.mipLevel member of each element of pRegions must be less than t= he mipLevels specified in VkImageCreateInfo when dstImage was cre= ated

  • The srcSubresource.baseArrayLayer +=20 srcSubresource.layerCount of each element of pReg= ions must be less than or equal to the arrayLayers specified in VkImageCreateInfo when srcImage was cre= ated

  • The dstSubresource.baseArrayLayer +=20 dstSubresource.layerCount of each element of pReg= ions must be less than or equal to the arrayLayers specified in VkImageCreateInfo when dstImage was cre= ated

Valid Usage (Implicit)
  • comm= andBuffer must be a valid Vk= CommandBuffer handle

  • srcImage<= /code> must be a valid VkImage handle

  • src= ImageLayout must be a valid VkImageLayout value

  • dstImage<= /code> must be a valid VkImage handle

  • dst= ImageLayout must be a valid VkImageLayout value

  • pRegions<= /code> must be a valid pointer to an arra= y of regionCount valid VkImageResolve structures<= /p>

  • comm= andBuffer must be in the recording state

  • The Vk= CommandPool that commandBuffer was allocated from must support graphics operations

  • This command must only be called outside of a render pass instan= ce

  • regi= onCount must be greater than 0

  • Each of command= Buffer, dstImage, and srcImage must have been created, allocated, or retrieved from= the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Gra= phics

Tra= nsfer

The VkImageResolve structure is defined as:

typedef struct VkImageResolve {
    VkImageSubresourceLayers    srcSubresource;
    VkOffset3D                  srcOffset;
    VkImageSubresourceLayers    dstSubresource;
    VkOffset3D                  dstOffset;
    VkExtent3D                  extent;
} VkImageResolve;
  • srcSubresource and dstSubresource are VkImageSubresourceLayers structures specifyin= g the image subresources of the images used for the source and destination image data, respectively. Resolve of depth/stencil images is not supported.

  • srcOffset and dstOffset select the initial x, y, and z offsets in texels of the sub-regions of the source and destination image data.

  • extent is the size in texels of the source image to resolve= in width, height and depth.

Valid Usage
  • The aspectMask member of srcSubresource and dstSubresource must only con= tain VK_IMAGE_ASPECT_COLOR_BIT

  • The layerCount member of srcSubresource and dstSubresource must match

  • If either of the calling command=E2=80=99s srcImage or d= stImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively

  • srcOffset.x and (extent.width = +=20 srcOffset.x) must bot= h be greater than or equal to 0 and less than or equal to the source image subresource width

  • srcOffset.y and (extent.height= +=20 srcOffset.y) must bot= h be greater than or equal to 0 and less than or equal to the source image subresource height

  • If the calling command=E2=80=99s srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be = 1.

  • srcOffset.z and (extent.depth = +=20 srcOffset.z) must bot= h be greater than or equal to 0 and less than or equal to the source image subresource depth

  • If the calling command=E2=80=99s srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then = srcOffset.z must be 0 and extent.d= epth must be 1.

  • dstOffset.x and (extent.width = +=20 dstOffset.x) must bot= h be greater than or equal to 0 and less than or equal to the destination image subresource width

  • dstOffset.y and (extent.height= +=20 dstOffset.y) must bot= h be greater than or equal to 0 and less than or equal to the destination image subresource height

  • If the calling command=E2=80=99s dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be = 1.

  • dstOffset.z and (extent.depth = +=20 dstOffset.z) must bot= h be greater than or equal to 0 and less than or equal to the destination image subresource depth

  • If the calling command=E2=80=99s dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then = dstOffset.z must be 0 and extent.d= epth must be 1.

Valid Usage (Implicit)
  • srcSub= resource must be a valid VkI= mageSubresourceLayers structure

  • dstSub= resource must be a valid VkI= mageSubresourceLayers structure

18.7. Buffer Markers

To write a 32-bit marker value into a buffer as a pipelined operation, c= all:

void vkCmdWriteBufferMarkerAMD(
    VkCommandBuffer                             commandBuffer,
    VkPipelineStageFlagBits                     pipelineStage,
    VkBuffer                                    dstBuffer,
    VkDeviceSize                                dstOffset,
    uint32_t                                    marker);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • pipelineStage is one of the VkPipe= lineStageFlagBits values, specifying the pipeline stage whose completion triggers the marker write.

  • dstBuffer is the buffer where the marker will be written to= .

  • dstOffset is the byte offset into the buffer where the mark= er will be written to.

  • marker is the 32-bit value of the marker.

The command will write the 32-bit marker value into the buffer only afte= r all preceding commands have finished executing up to at least the specified pipeline stage. This includes the completion of other preceding vkCmdWriteBufferMarkerAMD commands so long as their specified = pipeline stages occur either at the same time or earlier than this command=E2=80=99s specified pipelineStage.

While consecutive buffer marker writes with the same pipelineStage= parameter are implicitly complete in submission order, memory and execution dependencies between buffer marker writes and other operations must still b= e explicitly ordered using synchronization commands. The access scope for buffer marker writes falls under the VK_ACCESS_TRANSFER_WRITE_BIT, and the pipeline stages for iden= tifying the synchronization scope must include bo= th pipelineStage and VK_PIPELINE_STAGE_TRANSFER_BIT.

Note

Similar to vkCmdWriteTimestamp, if an implementation is una= ble to write a marker at any specific pipeline stage, it = may instead do so at any logically later stage.

Note

Implementations may only support a lim= ited number of pipelined marker write operations in flight at a given time, thus excessive number of marker write operations may degrade command execution = performance.

Valid Usage
  • dstOffset must be less than = or equal to the size of dstBuffer minus 4.

  • dstBuffer must have been cre= ated with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag

  • If dstBuffer is non-sparse then it mu= st be bound completely and contiguously to a single VkDeviceMemory object

  • dstOffset must be a multiple= of 4

Valid Usage (Implicit)
  • commandBuffer must be a valid = VkCommandBuffer handle

  • pipelineStage must be a valid = VkPipelineStageFlagBits value

  • = dstBuffer must be a valid Vk= Buffer handle

  • commandBuffer must be in the <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#c= ommandbuffers-lifecycle">recording state

  • The = VkCommandPool that commandBuffer was allocated fr= om must support transfer, graphics, or co= mpute operations

  • Both of commandBuffer, and dstBuffer = must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Tra= nsfer
Graphics
Compute

Tra= nsfer

19. Drawing Commands

Drawing commands (commands with Draw in the name) = provoke work in a graphics pipeline. Drawing commands are recorded into a command buffer and when executed by a queue, will produce work which executes according to the bound graphics pipeline. A graphics pipeline must be bound to a co= mmand buffer before any drawing commands are recorded in that command buffer.

Each draw is made up of zero or more vertices and zero or more instances= , which are processed by the device and result in the assembly of primitives. Primitives are assembled according to the pInputAssemblyState = member of the VkGraphicsPipelineCreateInfo structure, which is of typ= e VkPipelineInputAssemblyStateCreateInfo:

typedef struct VkPipelineInputA=
ssemblyStateCreateInfo {
    VkStructureType                            sType;
    const void*                                pNext;
    VkPipelineInputAssemblyStateCreateFlags    flags;
    VkPrimitiveTopology                        topology;
    VkBool32                                   primitiveRestartEnable;
} VkPipelineInputAssemblyStateCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • topology is a VkPrimitiveTopology = defining the primitive topology, as described below.

  • primitiveRestartEnable controls whether a special vertex in= dex value is treated as restarting the assembly of primitives. This enable only applies to indexed draws (vkCmdDrawIndex= ed and vkCmdDrawIndexedIndirect), and the special in= dex value is either 0xFFFFFFFF when the indexType parameter of vkCmdBindIndexBuffer is equal to VK_INDEX_TYPE_UINT32, or 0xFFFF when indexType is equal to VK_INDEX_TYPE_UINT16. Primitive restart is not allowed for =E2=80=9Clist=E2=80=9D topologies.

Restarting the assembly of primitives discards the most recent index val= ues if those elements formed an incomplete primitive, and restarts the primitiv= e assembly using the subsequent indices, but only assembling the immediately following element through the end of the originally specified elements. The primitive restart index value comparison is performed before adding the vertexOffset value to the index value.

Valid Usage
Valid Usage (Implicit)
  • <= code>sType must be VK_STRUCT= URE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO

  • <= code>pNext must be NULL

  • = flags must be 0

  • topology must be a val= id VkPrimitiveTopology value

typedef VkFlags VkPipelineInputAssemblyStateCreateFlags;

VkPipelineInputAssemblyStateCreateFlags is a bitmask type f= or setting a mask, but is currently reserved for future use.

19.1. Primitive Topologies

Primitive topology determines how consecutive vertices are orga= nized into primitives, and determines the type of primitive that is used at the beginning of the graphics pipeline. The effective topology for later stages of the pipeline is altered by tessellation or geometry shading (if either is in use) and depends on the execution modes of those shaders. Supported topologies are defined by VkPrimitiveTopolog= y and include:

typedef enum VkPrimitiveTopolog=
y {
    VK_PRIMITIVE_TOPOLOGY_POINT_LIST =3D 0,
    VK_PRIMITIVE_TOPOLOGY_LINE_LIST =3D 1,
    VK_PRIMITIVE_TOPOLOGY_LINE_STRIP =3D 2,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST =3D 3,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP =3D 4,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN =3D 5=
,
    VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY =3D 6,
    VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY =3D 7,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY =3D 8,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY =3D 9,
    VK_PRIMITIVE_TOPOLOGY_PATCH_LIST =3D 10,
} VkPrimitiveTopology;

Each primitive topology, and its construction from a list of vertices, i= s summarized below with a supporting diagram. In each diagram, the numbered points show the sequencing of vertices in order within the vertex arrays; however the positions chosen are arbitrary and for illustration only. Vertices connected with solid lines belong to the main primitives. In the primitive types with adjacency, the vertices connected by dashed lines are the adjacent vertices that are accessible in a geometry shader.

Note

The terminology =E2=80=9Cvertex i =E2=80=9D me= ans =E2=80=9Cthe vertex with index i in the ordered list of vertices defining = this primitive=E2=80=9D.

Note

Depending on the polygon mode, a polygon primitive generated from a drawing command with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, or VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY is rendere= d in one of several ways, such as outlining its border or filling its interior. The order of vertices in such a primitive is significant during polygon rasterization and fragment shading.

19.1.1. Point Lists

A series of individual points are specified with topology VK_PRIMITIVE_TOPOLOGY_POINT_LIST. Each vertex defines a separate point.

3D"primitive
Figure 12. Point Lists

19.1.2. Line Lists

Lists of line segments, with each segment defined by a pair of vertices,= are specified with topology VK_PRIMITIVE_TOPOLOGY_LINE_LIST<= /code>. The first two vertices define the first segment, with subsequent pairs of vertices each defining one more segment. If the number of vertices is odd, then the last vertex is ignored.

3D"primitive
Figure 13. Line Lists

19.1.3. Line Strips

A series of one or more connected line segments are specified with topology VK_PRIMITIVE_TOPOLOGY_LINE_STRIP. In this case, the first vertex specifies the first segment=E2=80=99s start = point while the second vertex specifies the first segment=E2=80=99s endpoint and = the second segment=E2=80=99s start point. In general, vertex i (for i &g= t; 0) specifies the beginning of the ith segment and the end of the previous segment. The last vertex specifies the end of the last segment. If only one vertex is specified, then no primitive is generated.

3D"=
Figure 14. Line Strips

19.1.4. Triangle Lists

Lists of separate triangles are specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST. In this case, vertices 3 i, 3 = i + 1, and 3 i + 2 (in that order) determine a triangle for each i =3D 0, 1= , =E2=80=A6=E2=80=8B, n-1, where there are 3 n + k vertices drawn. k is either 0, 1, or 2; if k is not zero, the final k vertices are ignored.

3D"primitive
Figure 15. Triangle Lists

19.1.5. Triangle Strips

A triangle strip is a series of triangles connected along shared edges, = and is specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGL= E_STRIP. In this case, the first three vertices define the first triangle, and their order is significant. Each subsequent vertex defines a new triangle using that point along with the last two vertices from the previous triangle. If fewer than three vertices are specified, no primitive is produced. The order of vertices in successive triangles changes as shown in the figur= e below, so that all triangle faces have the same orientation.

Figure 16. Triangle Strips

19.1.6. Triangle Fans

A triangle fan is specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN. It is similar to a triangle strip, but changes the vertex replaced from the previous triangle so that all triangles in the fan share a common vertex.

3D"primitive
Figure 17. Triangle Fans

19.1.7. Line Lists With Adjacency

Lines with adjacency are specified with topology VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, and are indepe= ndent line segments where each endpoint has a corresponding adjacent ver= tex that is accessible in a geometry shader. If a geometry shader is not active, the adjacent vertices are ignored.

A line segment is drawn from vertex 4 i + 1 t= o vertex 4 i + 2 for each i =3D 0, 1, =E2=80=A6=E2=80=8B, n-1= , where there are 4 n +=20 k vertices. k is either 0, 1, 2, or 3; if = k is not zero, the final k vertices are ignored. For line segment i, vertices 4= i and 4 i + 3 vertices are considered adjacent to vertices 4 i + 1 and = 4 i +=20 2, respectively.

Figure 18. Line Lists With Adjacency

19.1.8. Line Strips With Adjacency

Line strips with adjacency are specified with topology VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY and are simila= r to line strips, except that each line segment has a pair of adjacent vertices that are accessible in a geometry shader. If a geometry shader is not active, the adjacent vertices are ignored.

A line segment is drawn from vertex i + 1 ver= tex to vertex i + 2 for each i =3D 0, 1, =E2=80=A6=E2=80=8B, n-1= , where there are n +=20 3 vertices. If there are fewer than four vertices, all vertices are ignored. For line segment i, vertices i= and i + 3 are considered adjacent to vertices i + 1 and i + 2, respectively.

3D"primitive
Figure 19. Line Strips With Adjacency

19.1.9. Triangle Lists With Adjac= ency

Triangles with adjacency are specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, and are si= milar to separate triangles except that each triangle edge has an adjacent vertex that is accessible in a geometry shader. If a geometry shader is not active, the adjacent vertices are ignored.

Vertices 6 i, 6 i + 2, and 6 i + 4 (in that order) determine a triangle for each i =3D 0, 1, =E2=80= =A6=E2=80=8B, n-1, where there are 6 n+k vertices. k is either 0, 1, 2, 3, 4, or 5; if k is non-zero, the final k vertices are ignored. For triangle i, vertices 6 i += 1, 6 i + 3, and 6 i + 5 vertices are considered adjacent to edge= s from vertex 6 i to 6 i + 2, from <= span class=3D"eq">6 i + 2 to 6 i +=20 4, and from 6 i + 4 to 6 i vertices, respectively.

=3D"primitive
Figure 20. Triangle Lists With Adjacency

19.1.10. Triangle Strips With Ad= jacency

Triangle strips with adjacency are specified with topology VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, and are s= imilar to triangle strips except that each triangle edge has an adjacent vertex that is accessible in a geometry shader. If a geometry shader is not active, the adjacent vertices are ignored.

In triangle strips with adjacency, n triangles= are drawn where there are 2 (n + 2) + k vertices. k is either 0 or 1; if k is 1, the final vertex is ignored. If there are fewer than 6 vertices, the entire primitive is ignored.

3D"primitive
Figure 21. Triangle Strips With Adjacency

The table below illustrates the vertices and order used to draw each triangle, and which vertices are considered adjacent to each edge of those triangles. Each triangle is drawn using the vertices whose numbers are in the = 1st, 2nd, and 3rd columns under Primit= ive Vertices, in that order. The vertices in the 1/2, 2/3, and 3/1 columns under Adjacent Vertic= es are considered adjacent to the edges from the first to the second, from the second to the third, and from the third to the first vertex of the triangle= , respectively. The six rows correspond to six cases: the first and only triangle (i =3D 0, n =3D 1), the first triangle of several (i =3D= 0, n > 0), odd middle triangles (i =3D 1, 3, 5 =E2=80=A6=E2=80=8B), even middle triangles (i =3D 2, 4, 6, =E2=80=A6=E2=80=8B), and special cases for the last triangle, whe= n i is either even or odd. For the purposes of this table, both the first vertex and first triangle ar= e numbered 0.

Table 27. Triangles generated by triangle strips w= ith adjacency
Primitive Ver= tices Adjacent Vert= ices

Pri= mitive

1st=

2nd=

3rd=

1/2=

2/3=

3/1=

onl= y (i =3D 0, n =3D 1)

0

2

4

1

5

3

fir= st (i =3D 0)

0

2

4

1

6

3

mid= dle (i odd)

2 i + 2

2 i

2 i + 4

2 i-2

2 i + 3

2 i + 6

mid= dle (i even)

2 i

2 i + 2

2 i + 4

2 i-2

2 i + 6

2 i + 3

las= t (i=3Dn-1, i odd)

<= /td>

2 i + 2

2 i

2 i + 4

2 i-2

2 i + 3

2 i + 5

las= t (i=3Dn-1, i even)

=

2 i

2 i + 2

2 i + 4

2 i-2

2 i + 5

2 i + 3

19.1.11. Separate Patches

Separate patches are specified with topology VK_PRIMITIVE_TOPOLOGY_PATCH_LIST. A patch is an ordered collection of vertices used for primitive tessellation. The vertices comprising a patch have no implied geometric ordering, and are used by tessellation shaders and the fixed-function tessellator to generate new point, line, or triangle primitives.

Each patch in the series has a fixed number of vertices, specified by th= e patchControlPoints member of the VkPipelineTessellationStateCreateInf= o structure passed to vkCreateGraphicsPipelines. Once assembled and vertex shaded, these patches are provided as input to th= e tessellation control shader stage.

If the number of vertices in a patch is given by v, vertices v =C3=97 i through v =C3=97 i + v - 1 (in t= hat order) determine a patch for each i =3D 0, 1, =E2=80=A6=E2=80=8B, n-1, where there are v =C3=97 n + k vertices. k is in the range [0, v - 1]; if k is not zero, the final k vertices are ignored.

19.2. Primitive Order

Primitives generated by drawing commands progress through t= he stages of the graphics pipeline in primitive order. Primitive order is initially determined in the following way:

  1. Submission order determines the initial ordering

  2. For indirect draw commands, the order in which accessed instances of the VkDrawIndirectCommand are stored in buffer= , from lower indirect buffer addresses to higher addresses.

  3. If a draw command includes multiple instances, the order in which instances are executed, from lower numbered instances to higher.

  4. The order in which primitives are specified by a draw command:

    • For non-indexed draws, from vertices with a lower numbered vertexIndex to a higher numbered vertexIndex.

    • For indexed draws, vertices sourced from a lower index buffer addresses to higher addresses.

Within this order implementations further sort primitives:

  1. If tessellation shading is active, by an implementation-dependent order of new primitives generated by tessellation.

  2. If geometry shading is active, by the order new primitives are generated by geometry shading.

  3. If the polygon mode is not VK_POLYGON_MODE_FILL, or VK_POLYGON_MODE_FILL_RECTANGLE_NV, by an implementation-dependent ordering of the new primitives generated within the original primitive.

Primitive order is later used to define rasterization order, which determines the order in which fragments output results to = a framebuffer.

19.3. Programmable Primitive Sha= ding

Once primitives are assembled, they proceed to the vertex shading stage = of the pipeline. If the draw includes multiple instances, then the set of primitives is sent to the vertex shading stage multiple times, once for each instance.

It is undefined whether vertex shading occurs on vertices that are disca= rded as part of incomplete primitives, but if it does occur then it operates as if they were vertices in complete primitives and such invocations can have side effects.

Vertex shading receives two per-vertex inputs from the primitive assembl= y stage - the vertexIndex and the instanceIndex. How these values are generated is defined below, with each command.

Drawing commands fall roughly into two categories:

To bind an index buffer to a command buffer, call:

void vkCmdBindIndexBuffer(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    buffer,
    VkDeviceSize                                offset,
    VkIndexType                                 indexType);
  • commandBuffer is the command buffer into which the command = is recorded.

  • buffer is the buffer being bound.

  • offset is the starting offset in bytes within buffer<= /code> used in index buffer address calculations.

  • indexType is a VkIndexType value specifyin= g whether indices are treated as 16 bits or 32 bits.

Valid Usage
  • offset must be less than the= size of buffer

  • The sum of offset and the address of the range of VkDeviceMemory object that is backing buffer, must be a multiple of the type indicated by indexType

  • buffer must have been create= d with the VK_BUFFER_USAGE_INDEX_BUFFER_BIT flag

  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

Valid Usage (Implicit)
  • c= ommandBuffer must be a valid VkCommandBuffer handle

  • buffer must be a valid VkBuffer handle

  • index= Type must be a valid = VkIndexType value

  • c= ommandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • Both of buff= er, and commandBuffer must have been created, allocated, or retrieved from the same VkDevi= ce

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

Possible values of vkCmdBindIndexBuffer::indexType, specifying the size of indices, are:

typedef enum VkIndexType {
    VK_INDEX_TYPE_UINT16 =3D 0,
    VK_INDEX_TYPE_UINT32 =3D 1,
} VkIndexType;
  • VK_INDEX_TYPE_UINT16 specifies that indices are 16-bit unsi= gned integer values.

  • VK_INDEX_TYPE_UINT32 specifies that indices are 32-bit unsi= gned integer values.

The parameters for each drawing command are specified directly in the command or read from buffer memory, depending on the command. Drawing commands that source their parameters from buffer memory are known as indirect drawing commands.

All drawing commands interact with the Robust Buffer Access feature.

To record a non-indexed draw, call:

void vkCmdDraw(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    vertexCount,
    uint32_t                                    instanceCount,
    uint32_t                                    firstVertex,
    uint32_t                                    firstInstance);
  • commandBuffer is the command buffer into which the command = is recorded.

  • vertexCount is the number of vertices to draw.

  • instanceCount is the number of instances to draw.

  • firstVertex is the index of the first vertex to draw.

  • firstInstance is the instance ID of the first instance to d= raw.

When the command is executed, primitives are assembled using the current primitive topology and vertexCount consecutive vertex indices = with the first vertexIndex value equal to firstVertex. The primitives are drawn instanceCount times with instan= ceIndex starting with firstInstance and increasing sequentially for ea= ch instance. The assembled primitives execute the bound graphics pipeline.

Valid Usage
  • The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating= the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • The subpass index of the current render pass must<= /strong> be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, w= ith a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant valu= e must have been set for VK_PIPELINE_= BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point=E2=80=99s interface must have valid buffers bound

  • For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Vertex Input Description

  • A valid graphics pipeline must be bound t= o the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

  • If the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, th= at state must have been set on the current c= ommand buffer

  • Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uni= form buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a sto= rage buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IM= G as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_I= MG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, o= r VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must = be less than or equal to VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex.

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS reads from or writes to any im= age or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS writes to any image or buffer, that image or buffer must not be an unpro= tected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the framebuffer-space pipeline stages in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHI= CS reads from or writes to any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • If the bound graphics pipeline was created with VkPipelineSampleLocationsState= CreateInfoEXT::sampleLocationsEnable set to VK_TRUE and the current subpass has a depth/stencil attachment, then that attachment must hav= e been created with the VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT bit = set

Valid Usage (Implicit)
  • commandBuffe= r must be a valid VkCommandB= uffer handle

  • commandBuffe= r must be in the recording state

  • The VkCommandP= ool that commandBuffer was allocated from must support graphics operations

  • This command must only be called inside of a render pass instance

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

To record an indexed draw, call:

void vkCmdDrawIndexed(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    indexCount,
    uint32_t                                    instanceCount,
    uint32_t                                    firstIndex,
    int32_t                                     vertexOffset,
    uint32_t                                    firstInstance);
  • commandBuffer is the command buffer into which the command = is recorded.

  • indexCount is the number of vertices to draw.

  • instanceCount is the number of instances to draw.

  • firstIndex is the base index within the index buffer.

  • vertexOffset is the value added to the vertex index before indexing into the vertex buffer.

  • firstInstance is the instance ID of the first instance to d= raw.

When the command is executed, primitives are assembled using the current primitive topology and indexCount vertices whose indices are r= etrieved from the index buffer. The index buffer is treated as an array of tightly packed unsigned integers of size defined by the vkCmdBindIndexBuffer::indexType parameter with which the buffer was bound.

The first vertex index is at an offset of firstIndex * indexSize + offset within the bound index buffer, where offset is the offset specified by vkCmdBindIndexBuffer and indexSize is the byte size of the type specified by indexType. Subsequent index values are retrieved from consecutive locations in the index buffer. Indices are first compared to the primitive restart value, then zero extended to 32 bits (if the indexType is VK_INDEX_TYPE_U= INT16) and have vertexOffset added to them, before being supplied as = the vertexIndex value.

The primitives are drawn instanceCount times with ins= tanceIndex starting with firstInstance and increasing sequentially for ea= ch instance. The assembled primitives execute the bound graphics pipeline.

Valid Usage
  • The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating= the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • The subpass index of the current render pass must<= /strong> be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, w= ith a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant valu= e must have been set for VK_PIPELINE_= BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point=E2=80=99s interface must have valid buffers bound

  • For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Vertex Input Description

  • A valid graphics pipeline must be bound t= o the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

  • If the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, th= at state must have been set on the current c= ommand buffer

  • (indexSize * (firstIndex + indexCount) + offset) must be le= ss than or equal to the size of the bound index buffer, with indexSize being based on the type specified by indexType, where the index buffer, indexType, and offset are specified via vkCmdBindIndexBuffer

  • Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uni= form buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a sto= rage buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IM= G as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_I= MG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, o= r VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must = be less than or equal to VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex.

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS reads from or writes to any im= age or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS writes to any image or buffer, that image or buffer must not be an unpro= tected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the framebuffer-space pipeline stages in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHI= CS reads from or writes to any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • If the bound graphics pipeline was created with VkPipelineSampleLocationsState= CreateInfoEXT::sampleLocationsEnable set to VK_TRUE and the current subpass has a depth/stencil attachment, then that attachment must hav= e been created with the VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT bit = set

Valid Usage (Implicit)
  • comma= ndBuffer must be a valid VkC= ommandBuffer handle

  • comma= ndBuffer must be in the recording state

  • The VkC= ommandPool that commandBuffer was allocated from must support graphics operations

  • This command must only be called inside of a render pass instance=

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

To record a non-indexed indirect draw, call:

void vkCmdDrawIndirect(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    buffer,
    VkDeviceSize                                offset,
    uint32_t                                    drawCount,
    uint32_t                                    stride);
  • commandBuffer is the command buffer into which the command = is recorded.

  • buffer is the buffer containing draw parameters.

  • offset is the byte offset into buffer where pa= rameters begin.

  • drawCount is the number of draws to execute, and can be zero.

  • stride is the byte stride between successive sets of draw parameters.

vkCmdDrawIndirect behaves similarly to vkCmdDraw= except that the parameters are read by the device from a buffer during execution. drawCount draws are executed by the command, with parameters t= aken from buffer starting at offset and increasing by = stride bytes for each successive draw. The parameters of each draw are encoded in an array of VkDrawIndirectCommand structures. If drawCount is less than or equal to one, stride= is ignored.

Valid Usage
  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

  • buffer must have been create= d with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • offset must be a multiple of= 4

  • If drawCount is greater than 1, stride must be a multiple of 4 and must be greater tha= n or equal to sizeof(VkDrawIndirectCommand)

  • If the multi-draw indirect feature is not enabled, drawCount mus= t be 0 or 1

  • If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndirectCommand structures accessed by this command must be 0

  • The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating= the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • The subpass index of the current render pass must<= /strong> be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, w= ith a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant valu= e must have been set for VK_PIPELINE_= BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point=E2=80=99s interface must have valid buffers bound

  • A valid graphics pipeline must be bound t= o the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

  • If the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, th= at state must have been set on the current c= ommand buffer

  • If drawCount is equal to 1, (<= code>offset +=20 sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer

  • If drawCount is greater than 1, (stride =C3=97 (drawCount - 1) + offset +=20 sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer

  • drawCount must be less than = or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount

  • Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uni= form buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a sto= rage buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IM= G as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_I= MG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, o= r VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must = be less than or equal to VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex.

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS reads from or writes to any im= age or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS writes to any image or buffer, that image or buffer must not be an unpro= tected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the framebuffer-space pipeline stages in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHI= CS reads from or writes to any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • If the bound graphics pipeline was created with VkPipelineSampleLocationsState= CreateInfoEXT::sampleLocationsEnable set to VK_TRUE and the current subpass has a depth/stencil attachment, then that attachment must hav= e been created with the VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT bit = set

Valid Usage (Implicit)
  • comm= andBuffer must be a valid Vk= CommandBuffer handle

  • buffer must be a valid VkBuffer = handle

  • comm= andBuffer must be in the recording state

  • The Vk= CommandPool that commandBuffer was allocated from must support graphics operations

  • This command must only be called inside of a render pass instanc= e

  • Both of buffer<= /code>, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice<= /code>

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

The VkDrawIndirectCommand structure is defined as:

typedef struct VkDrawIndirectCo=
mmand {
    uint32_t    vertexCount;
    uint32_t    instanceCount;
    uint32_t    firstVertex;
    uint32_t    firstInstance;
} VkDrawIndirectCommand;
  • vertexCount is the number of vertices to draw.

  • instanceCount is the number of instances to draw.

  • firstVertex is the index of the first vertex to draw.

  • firstInstance is the instance ID of the first instance to d= raw.

The members of VkDrawIndirectCommand have the same meaning = as the similarly named parameters of vkCmdDraw.

Valid Usage
  • For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Vertex Input Description

  • If the drawIndirectFirstInstance feature is not enabled, firstInstance must be 0

To record a non-indexed draw call with a draw call count sourced from a buffer, call:

void vkCmdDrawIndirectCountKHR(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    buffer,
    VkDeviceSize                                offset,
    VkBuffer                                    countBuffer,
    VkDeviceSize                                countBufferOffset,
    uint32_t                                    maxDrawCount,
    uint32_t                                    stride);
  • commandBuffer is the command buffer into which the command = is recorded.

  • buffer is the buffer containing draw parameters.

  • offset is the byte offset into buffer where pa= rameters begin.

  • countBuffer is the buffer containing the draw count.

  • countBufferOffset is the byte offset into countBuffer= where the draw count begins.

  • maxDrawCount specifies the maximum number of draws that wil= l be executed. The actual number of executed draw calls is the minimum of the count specified in countBuffer and maxDrawCount.

  • stride is the byte stride between successive sets of draw parameters.

vkCmdDrawIndirectCountKHR behaves similarly to vkCmdDrawIndirect except that the draw count is read by the device from a buffer during execution. The command will read an unsigned 32-bit integer from countBuffer located at countBufferOffset and use this as the draw count.

Valid Usage
  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

  • buffer must have been create= d with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • If countBuffer is non-sparse then it = must be bound completely and contiguously to a single VkDeviceMemory object

  • countBuffer must have been c= reated with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • offset must be a multiple of= 4

  • countBufferOffset must be a = multiple of 4

  • stride must be a multiple of= 4 and must be greater than = or equal to sizeof(VkDrawIndirectCommand)

  • If maxDrawCount is greater than or equal to 1, (stride =C3=97 (maxDrawCount -= 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer

  • If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndirectCommand structures accessed by this command must be 0

  • The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating= the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • The subpass index of the current render pass must<= /strong> be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, w= ith a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant valu= e must have been set for VK_PIPELINE_= BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point=E2=80=99s interface must have valid buffers bound

  • A valid graphics pipeline must be bound t= o the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

  • If the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, th= at state must have been set on the current c= ommand buffer

  • If the count stored in countBuffer is equal to 1, (offset + sizeof(VkDrawIndirectComma= nd)) must be less than or equal to the size of buffer

  • If the count stored in countBuffer is greater than 1, (stride =C3=97 (drawCount - 1)= + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer

  • The count stored in countBuffer must<= /strong> be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount

  • Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uni= form buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a sto= rage buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IM= G as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_I= MG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, o= r VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must = be less than or equal to VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex.

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS reads from or writes to any im= age or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS writes to any image or buffer, that image or buffer must not be an unpro= tected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the framebuffer-space pipeline stages in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHI= CS reads from or writes to any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • If the bound graphics pipeline was created with VkPipelineSampleLocationsState= CreateInfoEXT::sampleLocationsEnable set to VK_TRUE and the current subpass has a depth/stencil attachment, then that attachment must hav= e been created with the VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT bit = set

Valid Usage (Implicit)
  • commandBuffer must be a valid = VkCommandBuffer handle

  • buf= fer must be a valid VkBuffer= handle

  • countBuffer must be a valid VkBuffer handle

  • commandBuffer must be in the <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#c= ommandbuffers-lifecycle">recording state

  • The = VkCommandPool that commandBuffer was allocated fr= om must support graphics operations

  • This command must only be called inside of a render pass= instance

  • Each of buffer, commandBuffer, and countBuffer must have been created, allocated, or retri= eved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

To record a non-indexed draw call with a draw call count sourced from a buffer, call:

void vkCmdDrawIndirectCountAMD(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    buffer,
    VkDeviceSize                                offset,
    VkBuffer                                    countBuffer,
    VkDeviceSize                                countBufferOffset,
    uint32_t                                    maxDrawCount,
    uint32_t                                    stride);
  • commandBuffer is the command buffer into which the command = is recorded.

  • buffer is the buffer containing draw parameters.

  • offset is the byte offset into buffer where pa= rameters begin.

  • countBuffer is the buffer containing the draw count.

  • countBufferOffset is the byte offset into countBuffer= where the draw count begins.

  • maxDrawCount specifies the maximum number of draws that wil= l be executed. The actual number of executed draw calls is the minimum of the count specified in countBuffer and maxDrawCount.

  • stride is the byte stride between successive sets of draw parameters.

vkCmdDrawIndirectCountAMD behaves similarly to vkCmdDrawIndirect except that the draw count is read by the device from a buffer during execution. The command will read an unsigned 32-bit integer from countBuffer located at countBufferOffset and use this as the draw count.

Valid Usage
  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

  • buffer must have been create= d with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • If countBuffer is non-sparse then it = must be bound completely and contiguously to a single VkDeviceMemory object

  • countBuffer must have been c= reated with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • offset must be a multiple of= 4

  • countBufferOffset must be a = multiple of 4

  • stride must be a multiple of= 4 and must be greater than = or equal to sizeof(VkDrawIndirectCommand)

  • If maxDrawCount is greater than or equal to 1, (stride =C3=97 (maxDrawCount -= 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer

  • If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndirectCommand structures accessed by this command must be 0

  • The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating= the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • The subpass index of the current render pass must<= /strong> be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, w= ith a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant valu= e must have been set for VK_PIPELINE_= BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point=E2=80=99s interface must have valid buffers bound

  • A valid graphics pipeline must be bound t= o the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

  • If the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, th= at state must have been set on the current c= ommand buffer

  • If the count stored in countBuffer is equal to 1, (offset + sizeof(VkDraw= IndirectCommand)) must be less than or equal to the size of= buffer

  • If the count stored in countBuffer is greater than 1, (stride =C3=97 (drawCount - 1)= + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer

  • The count stored in countBuffer must<= /strong> be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount

  • Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uni= form buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a sto= rage buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

  • If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must = be less than or equal to VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex.

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS reads from or writes to any im= age or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS writes to any image or buffer, that image or buffer must not be an unpro= tected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the framebuffer-space pipeline stages in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHI= CS reads from or writes to any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • If the bound graphics pipeline was created with VkPipelineSampleLocationsState= CreateInfoEXT::sampleLocationsEnable set to VK_TRUE and the current subpass has a depth/stencil attachment, then that attachment must hav= e been created with the VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT bit = set

Valid Usage (Implicit)
  • commandBuffer must be a valid = VkCommandBuffer handle

  • buf= fer must be a valid VkBuffer= handle

  • countBuffer must be a valid VkBuffer handle

  • commandBuffer must be in the <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#c= ommandbuffers-lifecycle">recording state

  • The = VkCommandPool that commandBuffer was allocated fr= om must support graphics operations

  • This command must only be called inside of a render pass= instance

  • Each of buffer, commandBuffer, and countBuffer must have been created, allocated, or retri= eved from the same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

To record an indexed indirect draw, call:

void vkCmdDrawIndexedIndirect(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    buffer,
    VkDeviceSize                                offset,
    uint32_t                                    drawCount,
    uint32_t                                    stride);
  • commandBuffer is the command buffer into which the command = is recorded.

  • buffer is the buffer containing draw parameters.

  • offset is the byte offset into buffer where pa= rameters begin.

  • drawCount is the number of draws to execute, and can be zero.

  • stride is the byte stride between successive sets of draw parameters.

vkCmdDrawIndexedIndirect behaves similarly to vkCmdDrawIndexed except that the parameters are read by the device from a buffer during execution. drawCount draws are executed by the command, with parameters t= aken from buffer starting at offset and increasing by = stride bytes for each successive draw. The parameters of each draw are encoded in an array of VkDrawIndexedIndirectCommand structures. If drawCount is less than or equal to one, stride= is ignored.

Valid Usage
  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

  • buffer must have been create= d with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • offset must be a multiple of= 4

  • If drawCount is greater than 1, stride must be a multiple of 4 and must be greater tha= n or equal to sizeof(VkDrawIndexedIndirectCommand)

  • If the multi-draw indirect feature is not enabled, drawCount mus= t be 0 or 1

  • If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndexedIndirectCommand structures accessed by this comma= nd must be 0

  • The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating= the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • The subpass index of the current render pass must<= /strong> be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, w= ith a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant valu= e must have been set for VK_PIPELINE_= BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point=E2=80=99s interface must have valid buffers bound

  • A valid graphics pipeline must be bound t= o the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

  • If the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, th= at state must have been set on the current c= ommand buffer

  • If drawCount is equal to 1, (<= code>offset +=20 sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer

  • If drawCount is greater than 1, (stride =C3=97 (drawCount - 1) + offset +=20 sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer

  • drawCount must be less than = or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount

  • Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uni= form buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a sto= rage buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IM= G as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_I= MG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, o= r VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • = If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must = be less than or equal to VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex.

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS reads from or writes to any im= age or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS writes to any image or buffer, that image or buffer must not be an unpro= tected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the framebuffer-space pipeline stages in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHI= CS reads from or writes to any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • If the bound graphics pipeline was created with VkPipelineSampleLocationsState= CreateInfoEXT::sampleLocationsEnable set to VK_TRUE and the current subpass has a depth/stencil attachment, then that attachment must hav= e been created with the VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT bit = set

Valid Usage (Implicit)
  • commandBuffer must be a valid <= code>VkCommandBuffer handle

  • buff= er must be a valid VkBuffer<= /code> handle

  • commandBuffer must be in the recording state

  • The <= code>VkCommandPool that commandBuffer was allocated fro= m must support graphics operations

  • This command must only be called inside of a render pass = instance

  • Both of = buffer, and commandBuffer must= have been created, allocated, or retrieved from the same Vk= Device

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

The VkDrawIndexedIndirectCommand structure is defined as:

typedef struct VkDrawIndexedInd=
irectCommand {
    uint32_t    indexCount;
    uint32_t    instanceCount;
    uint32_t    firstIndex;
    int32_t     vertexOffset;
    uint32_t    firstInstance;
} VkDrawIndexedIndirectCommand;
  • indexCount is the number of vertices to draw.

  • instanceCount is the number of instances to draw.

  • firstIndex is the base index within the index buffer.

  • vertexOffset is the value added to the vertex index before indexing into the vertex buffer.

  • firstInstance is the instance ID of the first instance to d= raw.

The members of VkDrawIndexedIndirectCommand have the same m= eaning as the similarly named parameters of vkCmdDrawIndexed.

Valid Usage
  • For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Vertex Input Description

  • (indexSize * (firstIndex + indexCount) + offset) must be le= ss than or equal to the size of the bound index buffer, with indexSize being based on the type specified by indexType, where the index buffer, indexTyp= e, and offset are specified via vkCmdBindIndexBuffer=

  • If the drawIndirectFirstInstance feature is not enabled, firstInstance must be 0

To record an indexed draw call with a draw call count sourced from a buf= fer, call:

void vkCmdDrawIndexedIndirectCountKHR(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    buffer,
    VkDeviceSize                                offset,
    VkBuffer                                    countBuffer,
    VkDeviceSize                                countBufferOffset,
    uint32_t                                    maxDrawCount,
    uint32_t                                    stride);
  • commandBuffer is the command buffer into which the command = is recorded.

  • buffer is the buffer containing draw parameters.

  • offset is the byte offset into buffer where pa= rameters begin.

  • countBuffer is the buffer containing the draw count.

  • countBufferOffset is the byte offset into countBuffer= where the draw count begins.

  • maxDrawCount specifies the maximum number of draws that wil= l be executed. The actual number of executed draw calls is the minimum of the count specified in countBuffer and maxDrawCount.

  • stride is the byte stride between successive sets of draw parameters.

vkCmdDrawIndexedIndirectCountKHR behaves similarly to vkCmdDrawIndexedIndirect except that the draw= count is read by the device from a buffer during execution. The command will read an unsigned 32-bit integer from countBuffer located at countBufferOffset and use this as the draw count.

Valid Usage
  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

  • buffer must have been create= d with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • If countBuffer is non-sparse then it = must be bound completely and contiguously to a single VkDeviceMemory object

  • countBuffer must have been c= reated with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • offset must be a multiple of= 4

  • = countBufferOffset must be a = multiple of 4

  • stride must be a multiple of= 4 and must be greater than = or equal to sizeof(VkDrawIndexedIndirectCommand)

  • If maxDrawCount is greater than or equal to 1, (stride =C3=97 (maxDrawCount -= 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer

  • If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndexedIndirectCommand structures accessed by this comma= nd must be 0

  • The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating= the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • The subpass index of the current render pass must<= /strong> be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, w= ith a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant valu= e must have been set for VK_PIPELINE_= BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point=E2=80=99s interface must have valid buffers bound

  • A valid graphics pipeline must be bound t= o the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

  • If the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, th= at state must have been set on the current c= ommand buffer

  • If count stored in countBuffer is equal to 1, (offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer

  • If count stored in countBuffer is greater than 1, (stride =C3=97 (drawCount - 1)= + offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer

  • drawCount must be less than = or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount

  • Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uni= form buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a sto= rage buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IM= G as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_I= MG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, o= r VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must = be less than or equal to VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex.

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS reads from or writes to any im= age or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS writes to any image or buffer, that image or buffer must not be an unpro= tected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the framebuffer-space pipeline stages in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHI= CS reads from or writes to any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • If the bound graphics pipeline was created with VkPipelineSampleLocationsState= CreateInfoEXT::sampleLocationsEnable set to VK_TRUE and the current subpass has a depth/stencil attachment, then that attachment must hav= e been created with the VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT bit = set

Valid Usage (Implicit)
Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

To record an indexed draw call with a draw call count sourced from a buf= fer, call:

void vkCmdDrawIndexedIndirectCountAMD(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    buffer,
    VkDeviceSize                                offset,
    VkBuffer                                    countBuffer,
    VkDeviceSize                                countBufferOffset,
    uint32_t                                    maxDrawCount,
    uint32_t                                    stride);
  • commandBuffer is the command buffer into which the command = is recorded.

  • buffer is the buffer containing draw parameters.

  • offset is the byte offset into buffer where pa= rameters begin.

  • countBuffer is the buffer containing the draw count.

  • countBufferOffset is the byte offset into countBuffer= where the draw count begins.

  • maxDrawCount specifies the maximum number of draws that wil= l be executed. The actual number of executed draw calls is the minimum of the count specified in countBuffer and maxDrawCount.

  • stride is the byte stride between successive sets of draw parameters.

vkCmdDrawIndexedIndirectCountAMD behaves similarly to vkCmdDrawIndexedIndirect except that the draw= count is read by the device from a buffer during execution. The command will read an unsigned 32-bit integer from countBuffer located at countBufferOffset and use this as the draw count.

Valid Usage
  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

  • buffer must have been create= d with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • If countBuffer is non-sparse then it = must be bound completely and contiguously to a single VkDeviceMemory object

  • countBuffer must have been c= reated with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • offset must be a multiple of= 4

  • = countBufferOffset must be a = multiple of 4

  • stride must be a multiple of= 4 and must be greater than = or equal to sizeof(VkDrawIndexedIndirectCommand)

  • If maxDrawCount is greater than or equal to 1, (stride =C3=97 (maxDrawCount -= 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) <= strong class=3D"purple">must be less than or equal to the size of buffer

  • If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndexedIndirectCommand structures accessed by this comma= nd must be 0

  • The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating= the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • The subpass index of the current render pass must<= /strong> be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, w= ith a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant valu= e must have been set for VK_PIPELINE_= BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point=E2=80=99s interface must have valid buffers bound

  • A valid graphics pipeline must be bound t= o the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

  • If the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, th= at state must have been set on the current c= ommand buffer

  • If count stored in countBuffer is equal to 1, (offset + sizeof(VkDrawIndexedIndirectCommand)) <= strong class=3D"purple">must be less than or equal to the size of buffer

  • If count stored in countBuffer is greater than 1, (stride =C3=97 (drawCount - 1)= + offset + sizeof(VkDrawIndexedIndirectCommand)) <= strong class=3D"purple">must be less than or equal to the size of buffer

  • drawCount must be less than = or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount

  • Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uni= form buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a sto= rage buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

  • If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must = be less than or equal to VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex.

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS reads from or writes to any im= age or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHICS writes to any image or buffer, that image or buffer must not be an unpro= tected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the framebuffer-space pipeline stages in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_GRAPHI= CS reads from or writes to any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • If the bound graphics pipeline was created with VkPipelineSampleLocationsState= CreateInfoEXT::sampleLocationsEnable set to VK_TRUE and the current subpass has a depth/stencil attachment, then that attachment must hav= e been created with the VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT bit = set

Valid Usage (Implicit)
Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics

Gra= phics

19.4. Conditional Rendering

Certain rendering commands can be exec= uted conditionally based on a value in buffer memory. These rendering commands are limited to drawing commands, dispatching commands, and clearing attachments with vkCmdClearAttachments within a conditional rende= ring block which is defined by commands vkCmdBeginConditiona= lRenderingEXT and vkCmdEndConditionalRenderingEXT. Other rendering commands remain unaffected by conditional rendering.

After beginning conditional rendering, it is considered active = within the command buffer it was called until it is ended with vkCmdEndConditionalRenderingEXT.

Conditional rendering must begin and e= nd in the same command buffer. When conditional rendering is active, a primary command buffer can execute secondary command buffers if the inherited conditional rendering feature is enabled. For a secondary command buffer to be executed while conditional rendering i= s active in the primary command buffer, it must set the conditionalRenderingEnable flag of VkCommandBufferInher= itanceConditionalRenderingInfoEXT, as described in the Command Buffer Recording section.

Conditional rendering must also either= begin and end inside the same subpass of a render pass instance, or must both begin and end outside of a render pass instance (i.e. contain entire render pass instances).

To begin conditional rendering, call:

void vkCmdBeginConditionalRenderingEXT(
    VkCommandBuffer                             commandBuffer,
    const VkConditionalRenderingBeginInfoE=
XT*   pConditionalRenderingBegin);
  • commandBuffer is the command buffer into which this command= will be recorded.

  • pConditionalRenderingBegin is a pointer to an instance of t= he VkConditionalRenderingBeginInfoEXT = structure specifying the parameters of conditional rendering.

Valid Usage
  • Conditional rendering must not already be active

Valid Usage (Implicit)
Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

The VkConditionalRenderingBeginInfoEXT structure is defined= as:

typedef struct VkConditionalRen=
deringBeginInfoEXT {
    VkStructureType                   sType;
    const void*                       pNext;
    VkBuffer                          buffer;
    VkDeviceSize                      offset;
    VkConditionalRenderingFlagsEXT    flags;
} VkConditionalRenderingBeginInfoEXT;

If the 32-bit value at offset in buffer memory= is zero, then the rendering commands are discarded, otherwise they are executed as normal. If the value of the predicate in buffer memory changes while conditional rendering is active, the rendering commands may be discarded in an implementation-dependent way. Some implementations may latch the value of the predicate upon beginning conditional rendering while others may read it before every rendering command.

Valid Usage
  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

  • buffer must have been create= d with the VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT bit set

  • offset must be less than the= size of buffer by at least 32 bits.

  • offset must be a multiple of= 4

Bits which can be set in vkCmdBeginConditionalRenderingEXT::<= code>flags specifying the behavior of conditional rendering are:

typedef enum VkConditionalRende=
ringFlagBitsEXT {
    VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT =3D 0x000=
00001,
} VkConditionalRenderingFlagBitsEXT;
  • VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT specifies the con= dition used to determine whether to discard rendering commands or not. That is, if the 32-bit predicate read from buffer memory at offset is zero, the rendering commands are not discarded, and = if non zero, then they are discarded.

typedef VkFlags VkConditionalRenderingFlagsEXT;

VkConditionalRenderingFlagsEXT is a bitmask type for settin= g a mask of zero or more VkConditionalRenderingFlagB= itsEXT.

20. Fixed-Function Vertex Processing

Vertex fetching is controlled via configurable state, as a logically distinct graphics pipeline stage.

20.1. Vertex Attributes

Vertex shaders can define input variab= les, which receive vertex attribute data transferred from one or more VkBuffer(s) by drawing comma= nds. Vertex shader input variables are bound to buffers via an indirect binding where the vertex shader associates a vertex input attribute number= with each variable, vertex input attributes are associated to vertex input bindings on a per-pipeline basis, and vertex input bindings are associ= ated with specific buffers on a per-draw basis via the vkCmdBindVertexBuffers command. Vertex input attribute and vertex input binding descriptions also contain format information controlling how data is extracted from buffer memory and converted to the format expected by the vertex shader.

There are VkPhysicalDeviceLimits::maxVertexInputAttri= butes number of vertex input attributes and VkPhysicalDeviceLimits::maxVertexInputBindings nu= mber of vertex input bindings (each referred to by zero-based indices), where there are at least as many vertex input attributes as there are vertex input bindings. Applications can store multiple vertex in= put attributes interleaved in a single buffer, and use a single vertex input binding to access those attributes.

In GLSL, vertex shaders associate input variables with a vertex input attribute number using the location layout qualifier. The component layout qualifier associates components of a vert= ex shader input variable with components of a vertex input attribute.

GLSL example
// Assign locatio=
n M to variableName
layout (location=3DM, component=3D2) in vec2 variableName;

// Assign locations [N,N+L) to the array elements of variableNameArray
layout (location=3DN) in vec4 variableNameArray[L];

In SPIR-V, vertex shaders associate input variables with a vertex input attribute number using the Location decoration. The Component decoration associates components of a vertex sha= der input variable with components of a vertex input attribute. The Location and Component decorations are specif= ied via the OpDecorate instruction.

SPIR-V example
               .=
..
          %1 =3D OpExtInstImport "GLSL.std.450"
               ...
               OpName %9 "variableName"
               OpName %15 "variableNameArray"
               OpDecorate %18 BuiltIn VertexIndex
               OpDecorate %19 BuiltIn InstanceIndex
               OpDecorate %9 Location M
               OpDecorate %9 Component 2
               OpDecorate %15 Location N
               ...
          %2 =3D OpTypeVoid
          %3 =3D OpTypeFunction %2
          %6 =3D OpTypeFloat 32
          %7 =3D OpTypeVector %6 2
          %8 =3D OpTypePointer Input %7
          %9 =3D OpVariable %8 Input
         %10 =3D OpTypeVector %6 4
         %11 =3D OpTypeInt 32 0
         %12 =3D OpConstant %11 L
         %13 =3D OpTypeArray %10 %12
         %14 =3D OpTypePointer Input %13
         %15 =3D OpVariable %14 Input
               ...

20.1.1. Attribute Location and Componen= t Assignment

Vertex shaders allow Location and Component de= corations on input variable declarations. The Location decoration specifies which vertex input attribute= is used to read and interpret the data that a variable will consume. The Component decoration allows the location to be more finely specified for scalars and vectors, down to the individual components within a location that are consumed. The components within a location are 0, 1, 2, and 3. A variable starting at component N will consume components N, N+1, N+2, =E2= =80=A6=E2=80=8B up through its size. For single precision types, it is invalid if the sequence of components get= s larger than 3.

Table 28. Input attribute components accessed by 3= 2-bit input variables
32-bit data type Component deco= ration Components consumed

sca= lar

0 o= r unspecified

(x,= o, o, o)

sca= lar

1

(o,= y, o, o)

sca= lar

2

(o,= o, z, o)

sca= lar

3

(o,= o, o, w)

two= -component vector

0 o= r unspecified

(x,= y, o, o)

two= -component vector

1

(o,= y, z, o)

two= -component vector

2

(o,= o, z, w)

thr= ee-component vector

0 o= r unspecified

(x,= y, z, o)

thr= ee-component vector

1

(o,= y, z, w)

fou= r-component vector

0 o= r unspecified

(x,= y, z, w)

Components indicated by =E2=80=9Co=E2=80=9D are available for use by oth= er input variables which are sourced from the same attribute, and if used, are either filled with the corresponding component from the input format (if present), or the default value.

When a vertex shader input variable declared using a 32-bit floating poi= nt matrix type is assigned a location i, its values are taken from consecutive input attributes starting with the corresponding VkVertexInputAttributeDescription::location. Such matrices are treated as an array of column vectors with values taken from the input attributes identified in Input attri= butes accessed by 32-bit input matrix variables. The VkVertexInputAttributeDescription::format must be specified with a VkFormat that corresponds to the appropriate type of c= olumn vector. The Component decoration must not be used with matrix types.

Table 29. Input attributes accessed by 32-bit inpu= t matrix variables
Data type Column vector type Locations consumed Components consumed

mat= 2

two= -component vector

i, = i+1

(x,= y, o, o), (x, y, o, o)

mat= 2x3

thr= ee-component vector

i, = i+1

(x,= y, z, o), (x, y, z, o)

mat= 2x4

fou= r-component vector

i, = i+1

(x,= y, z, w), (x, y, z, w)

mat= 3x2

two= -component vector

i, = i+1, i+2

(x,= y, o, o), (x, y, o, o), (x, y, o, o)

mat= 3

thr= ee-component vector

i, = i+1, i+2

(x,= y, z, o), (x, y, z, o), (x, y, z, o)

mat= 3x4

fou= r-component vector

i, = i+1, i+2

(x,= y, z, w), (x, y, z, w), (x, y, z, w)

mat= 4x2

two= -component vector

i, = i+1, i+2, i+3

(x,= y, o, o), (x, y, o, o), (x, y, o, o), (x, y, o, o)

mat= 4x3

thr= ee-component vector

i, = i+1, i+2, i+3

(x,= y, z, o), (x, y, z, o), (x, y, z, o), (x, y, z, o)

mat= 4

fou= r-component vector

i, = i+1, i+2, i+3

(x,= y, z, w), (x, y, z, w), (x, y, z, w), (x, y, z, w)

Components indicated by =E2=80=9Co=E2=80=9D are available for use by oth= er input variables which are sourced from the same attribute, and if used, are either filled with the corresponding component from the input (if present), or the defaul= t value.

When a vertex shader input variable declared using a scalar or vector 64= -bit data type is assigned a location i, its values are taken from cons= ecutive input attributes starting with the corresponding VkVertexInputAttributeDescription::location. The locations and components used depend on the type of variable and the Component decoration specified in the variable declaration, as identified in Input attribute locations and compone= nts accessed by 64-bit input variables. For 64-bit data types, no default attribute values are provided. Input variables must not use more compone= nts than provided by the attribute. Input attributes which have one- or two-component 64-bit formats will consume a single location. Input attributes which have three- or four-component 64-bit formats will consume two consecutive locations. A 64-bit scalar data type will consume two components, and a 64-bit two-component vector data type will consume all four components available within a location. A three- or four-component 64-bit data type must not specify a component. A three-component 64-bit data type will consume all four components of the first location and components 0 and 1 of the second location. This leaves components 2 and 3 available for other component-qualified declarations. A four-component 64-bit data type will consume all four components of the first location and all four components of the second location. It is invalid for a scalar or two-component 64-bit data type to specify a component of 1 or 3.

Table 30. Input attribute locations and components= accessed by 64-bit input variables
Input format Locations consumed 64-bit data type Location dec= oration Component de= coration 32-bit components consume= d

R64=

i=

sca= lar

i=

0= or unspecified

(x,= y, -, -)

R64G64

i

sca= lar

i=

0= or unspecified

(x,= y, o, o)

sca= lar

i=

2

(= o, o, z, w)

two= -component vector

i=

0 o= r unspecified

(= x, y, z, w)

R64G64B64

i, i+1

sca= lar

i=

0= or unspecified

(x,= y, o, o), (o, o, -, -)

sca= lar

i=

2

(= o, o, z, w), (o, o, -, -)

sca= lar

i= +1

0 o= r unspecified

(= o, o, o, o), (x, y, -, -)

two= -component vector

i=

0 o= r unspecified

(= x, y, z, w), (o, o, -, -)

thr= ee-component vector

i=

uns= pecified

(= x, y, z, w), (x, y, -, -)

R64G64B64A64

i, i+1

sca= lar

i=

0= or unspecified

(x,= y, o, o), (o, o, o, o)

sca= lar

i=

2

(= o, o, z, w), (o, o, o, o)

sca= lar

i= +1

0 o= r unspecified

(= o, o, o, o), (x, y, o, o)

sca= lar

i= +1

2

(= o, o, o, o), (o, o, z, w)

two= -component vector

i=

0 o= r unspecified

(= x, y, z, w), (o, o, o, o)

two= -component vector

i= +1

0 o= r unspecified

(= o, o, o, o), (x, y, z, w)

thr= ee-component vector

i=

uns= pecified

(= x, y, z, w), (x, y, o, o)

fou= r-component vector

i=

uns= pecified

(= x, y, z, w), (x, y, z, w)

Components indicated by =E2=80=9Co=E2=80=9D are available for use by oth= er input variables which are sourced from the same attribute. Components indicated by =E2=80=9C-=E2=80=9D are not available for input var= iables as there are no default values provided for 64-bit data types, and there is no data provided by the input format.

When a vertex shader input variable declared using a 64-bit floating-poi= nt matrix type is assigned a location i, its values are taken from consecutive input attribute locations. Such matrices are treated as an array of column vectors with values taken from the input attributes as shown in Input attribu= te locations and components accessed by 64-bit input variables. Each column vector starts at the location immediately following the last location of the previous column vector. The number of attributes and components assigned to each matrix is determined by the matrix dimensions and ranges from two to eight locations.=

When a vertex shader input variable declared using an array type is assi= gned a location, its values are taken from consecutive input attributes starting with the corresponding VkVertexInputAttributeDescription::location. The number of attributes and components assigned to each element are determined according to the data type of the array elements and Component decoration (if any) specified in the declaration of = the array, as described above. Each element of the array, in order, is assigned to consecutive locations, but all at the same specified component within each location.

Only input variables declared with the data types and component decorati= ons as specified above are supported. Location aliasing is causing two variables to have the same locati= on number. Component aliasing is assigning the same (or overlapping) componen= t number for two location aliases. Location aliasing is allowed only if it does not cause component aliasing. Further, when location aliasing, the aliases sharing the location must all have the same SPIR-V floating-point component type or all have the same width integer-type components.

20.2. Vertex Input Description

Applications specify vertex input attribute and vertex input binding descriptions as part of graphics pipeline creation. The VkGraphicsPipelineCreateInfo::p= VertexInputState points to a structure of type VkPipelineVertexInputStateCreateInfo.

The VkPipelineVertexInputStateCreateInfo structure is defin= ed as:

typedef struct VkPipelineVertex=
InputStateCreateInfo {
    VkStructureType                             sType;
    const void*                                 pNext;
    VkPipelineVertexInputStateCreateFlags       flags;
    uint32_t                                    vertexBindingDescriptionCou=
nt;
    const VkVertexInputBindingDescription*=
      pVertexBindingDescriptions;
    uint32_t                                    vertexAttributeDescriptionC=
ount;
    const VkVertexInputAttributeDescriptio=
n*    pVertexAttributeDescriptions;
} VkPipelineVertexInputStateCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • vertexBindingDescriptionCount is the number of vertex bindi= ng descriptions provided in pVertexBindingDescriptions.

  • pVertexBindingDescriptions is a pointer to an array of VkVertexInputBindingDescription structures.

  • vertexAttributeDescriptionCount is the number of vertex att= ribute descriptions provided in pVertexAttributeDescriptions.

  • pVertexAttributeDescriptions is a pointer to an array of VkVertexInputAttributeDescription structures.

Valid Usage
  • vertexBindingDescriptionCount must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings

  • vertexAttributeDescriptionCount must<= /strong> be less than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes<= /p>

  • For every binding specified by each element of pVertexAttributeDescriptions, a VkVertexInputBindingDescription must<= /strong> exist in pVertexBindingDescriptions with the same value of bindin= g

  • All elements of pVertexBindingDescriptions must describe distinct binding numbers

  • All elements of pVertexAttributeDescriptions must describe distinct attribute locations

Valid Usage (Implicit)
  • sType must be VK_STRUCTUR= E_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO

  • pNext must be NULL= or a pointer to a valid instance of VkPipelineVertexInputDivisorStateCreateInfoEXT

  • flags must be 0

  • If vertexBindingDescriptionCount is not = 0, pVertexBindingDescriptions must be a valid pointer to an array of vertexBindingDe= scriptionCount valid VkVertexInputBindingDescription st= ructures

  • If vertexAttributeDescriptionCount is = not 0, pVertexAttributeDescriptions must be a valid pointer to an array of vertexAtt= ributeDescriptionCount valid VkVertexInputAttributeDescription= structures

typedef VkFlags VkPipelineVertexInputStateCreateFlags;<=
/pre>

VkPipelineVertexInputStateCreateFlags is a bitmask type for= setting a mask, but is currently reserved for future use.

Each vertex input binding is specified by an instance of the VkVertexInputBindingDescription structure.

The VkVertexInputBindingDescription structure is defined as= :

typedef struct VkVertexInputBin=
dingDescription {
    uint32_t             binding;
    uint32_t             stride;
    VkVertexInputRate    inputRate;
} VkVertexInputBindingDescription;
  • binding is the binding number that this structure describes= .

  • stride is the distance in bytes between two consecutive ele= ments within the buffer.

  • inputRate is a VkVertexInputRate val= ue specifying whether vertex attribute addressing is a function of the vertex index or of the instance index.

Valid Usage
  • binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings

  • stride must be less than or = equal to VkPhysicalDeviceLimits::maxVertexInputBindingStride

Valid Usage (Implicit)
  • = inputRate must be a valid VkVertexInputRate value

Possible values of VkVertexInputBinding= Description::inputRate, specifying the rate at which vertex attributes are pulled from buffers, are= :

typedef enum VkVertexInputRate =
{
    VK_VERTEX_INPUT_RATE_VERTEX =3D 0,
    VK_VERTEX_INPUT_RATE_INSTANCE =3D 1,
} VkVertexInputRate;
  • VK_VERTEX_INPUT_RATE_VERTEX specifies that vertex attribute addressing is a function of the vertex index.

  • VK_VERTEX_INPUT_RATE_INSTANCE specifies that vertex attribu= te addressing is a function of the instance index.

Each vertex input attribute is specified by an instance of the VkVertexInputAttributeDescription structure.

The VkVertexInputAttributeDescription structure is defined = as:

typedef struct VkVertexInputAtt=
ributeDescription {
    uint32_t    location;
    uint32_t    binding;
    VkFormat    format;
    uint32_t    offset;
} VkVertexInputAttributeDescription;
  • location is the shader binding location number for this att= ribute.

  • binding is the binding number which this attribute takes it= s data from.

  • format is the size and type of the vertex attribute data.

  • offset is a byte offset of this attribute relative to the s= tart of an element in the vertex input binding.

Valid Usage
  • location must be less than VkPhysicalDeviceLimits::maxVertexInputAttributes<= /p>

  • binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings

  • offset must be less than or = equal to VkPhysicalDeviceLimits::maxVertexInputAttributeOffset

  • format must be allowed as a = vertex buffer format, as specified by the VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties

Valid Usage (Implicit)
  • <= code>format must be a valid VkFormat value

To bind vertex buffers to a command buffer for use in subsequent draw commands, call:

void vkCmdBindVertexBuffers(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstBinding,
    uint32_t                                    bindingCount,
    const VkBuffer*                       =
      pBuffers,
    const VkDeviceSize*                   =
      pOffsets);
  • commandBuffer is the command buffer into which the command = is recorded.

  • firstBinding is the index of the first vertex input binding= whose state is updated by the command.

  • bindingCount is the number of vertex input bindings whose s= tate is updated by the command.

  • pBuffers is a pointer to an array of buffer handles.

  • pOffsets is a pointer to an array of buffer offsets.

The values taken from elements i of pBuf= fers and pOffsets replace the current state for the vertex input binding firstBinding + i, for i in [0, bindingCount). The vertex input binding is updated to start at the offset indicated by pOffsets[i] from the start of the buffer pBuffers= [i]. All vertex input attributes that use each of these bindings will use these updated addresses in their address calculations for subsequent draw commands.

Valid Usage
  • firstBinding must be less th= an VkPhysicalDeviceLimits::maxVertexInputBindings

  • The sum of firstBinding and bindingCount must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindin= gs

  • All elements of pOffsets must be less than the size of the corresponding element in pBuffers

  • All elements of pBuffers must have been created with the VK_BUFFER_USAGE_VERTEX_BUFFER_BIT flag

  • Each element of pBuffers that is non-sparse must be bound completely and contiguously to a single VkDeviceMemory object<= /p>

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • pBuf= fers must be a valid pointer to an= array of bindingCount valid VkBuffer handles

  • pOff= sets must be a valid pointer to an= array of bindingCount VkDeviceSize values

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from = must support graphics operations

  • bindingCount must be greater tha= n 0

  • Both of co= mmandBuffer, and the elements of pBuffers must have been created, allocated, or retrieved from t= he same VkDevice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

20.3. Vertex At= tribute Divisor in Instanced Rendering

If the pNext chain of VkPipelineVertexInputStateCreateInfo includes a VkPipelineVertexInputDivisorStateCreateInfoEXT stru= cture, then that structure controls how vertex attributes are assigned to an instance when instanced rendering is enabled.

The VkPipelineVertexInputDivisorStateCreateInfoEXT structur= e is defined as:

typedef struct VkPipelineVertex=
InputDivisorStateCreateInfoEXT {
    VkStructureType                                     sType;
    const void*                                         pNext;
    uint32_t                                            vertexBindingDiviso=
rCount;
    const VkVertexInputBindingDivisorDescr=
iptionEXT*    pVertexBindingDivisors;
} VkPipelineVertexInputDivisorStateCreateInfoEXT;
  • sType is the type of this structure

  • pNext is NULL or a pointer to an extension-spe= cific structure

  • vertexBindingDivisorCount is the number of elements in the pVertexBindingDivisors array.

  • pVertexBindingDivisors is a pointer to an array of VkVertexInputBindingDivisorDescriptionEXT structures, which specifies the divisor value for each binding.

Valid Usage (Implicit)
  • sType must be V= K_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT=

  • pVertexBindingDivisors must be a valid pointer to an array of vertexB= indingDivisorCount VkVertexInputBindingDivisorDescriptionEXT structures

  • vertexBindingDivisorCount must be greater than 0

The individual divisor values per binding are specified using the VkVertexInputBindingDivisorDescriptionEXT structure which is d= efined as:

typedef struct VkVertexInputBin=
dingDivisorDescriptionEXT {
    uint32_t    binding;
    uint32_t    divisor;
} VkVertexInputBindingDivisorDescriptionEXT;
  • binding is the binding number for which the divisor is spec= ified.

  • divisor is the the number of successive instances that will= use the same value of the vertex attribute when instanced rendering is enabled. For example, if the divisor is N, the same vertex attribute will applied to N successive instances before moving on to the next vertex attribute. The maximum value of divisor is implementation dependent and can be queried using VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT::max= VertexAttribDivisor.

If this structure is not used to define a divisor value for an attribute then the divisor has a logical default value of 1.

The address of each attribute for each vertexIndex and instanceIndex is calculated as follows:

  • Let attribDesc be the member of VkPipelineVertexInputStateCreateInfo::pVertexAttributeDe= scriptions with VkVertexInputAttributeDescription::location = equal to the vertex input attribute number.

  • Let bindingDesc be the member of VkPipelineVertexInputStateCreateInfo::pVertexBindingDesc= riptions with VkVertexInputAttributeDescription::binding e= qual to attribDesc.binding.

  • Let vertexIndex be the index of the vertex within the draw = (a value between firstVertex and firstVertex+vertexC= ount for vkCmdDraw, or a value taken from the index buffer for vkCmdDrawIndexed), and let instanceIndex be the i= nstance number of the draw (a value between firstInstance and firstInstance+instanceCount).

  • Let divisor be the member of VkPipelineVertexInputDivisorStateCreateInfoEXT::pVertexB= indingDivisors with VkVertexInputBindingDivisorDescriptionEXT::binding<= /code> equal to attribDesc.binding.

bufferBindingAddress=
 =3D buffer[binding].baseAddress + offset[binding];

if (bindingDesc.inputRate =3D=3D VK_VERTEX_I=
NPUT_RATE_VERTEX)
    vertexOffset =3D vertexIndex * bindingDesc.stride;
else
    vertexOffset =3D (firstInstance + ((instanceIndex - firstInstance) / di=
visor)) * bindingDesc.stride;

attribAddress =3D bufferBindingAddress + vertexOffset + attribDesc.offset;<=
/code>

For each attribute, raw data is extracted starting at attribAddres= s and is converted from the VkVertexInputAttributeDescription=E2=80=99s= format to either to floating-point, unsigned integer, or signed integer based on the base type of the format; the base type of the format must match the base type of the input variable in the shader. If format is a packed format, attribAddress must be a multiple of the size in bytes of the whole attribute data type as described in Packed Formats. Otherwise, attribAddress must be a multiple of the size in bytes of the component type indicated by format (see Form= ats). If the format does not include G, B, or A components, then those are filled with (0,0,1) as needed (using either 1.0f or inte= ger 1 based on the format) for attributes that are not 64-bit data types. The number of components in the vertex shader input variable need not exactly match the number of components in the format. If the vertex shader has fewer components, the extra components are discarded.

20.4. Example

To create a graphics pipeline that uses the following vertex description= :

struct Vertex
{
    float   x, y, z, w;
    uint8_t u, v;
};

The application could use the following set of structures:

const VkVertexInputBindingDescription binding =3D
{
    0,                                      =
    // binding
    sizeof(Vertex),                         =
    // stride
    VK_VERTEX_INPUT_RATE_VERTEX                 // =
inputRate
};

const VkVertexInputAttributeDescription at=
tributes[] =3D
{
    {
        0,                                  =
    // location
        binding.binding,                        // =
binding
        VK_FORMAT_R32G32B32A32_SFLOAT,          // =
format
        0                                   =
    // offset
    },
    {
        1,                                  =
    // location
        binding.binding,                        // =
binding
        VK_FORMAT_R8G8_UNORM,                   // =
format
        4 * sizeof(float)                       <=
span class=3D"comment">// offset
    }
};

const VkPipelineVertexInputStateCreateInfo=
 viInfo =3D
{
    VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO,    // sType
    NULL,                       =
  // pNext
    0,                            // flags
    1,                            // vertexBindingDescriptionCount
    &binding,                     // pVertexBin=
dingDescriptions
    2,                            // vertexAttributeDescriptionCount
    &attributes[0]                // pVertexAttributeDescriptions
};

21. Tessellation

Tessellation involves three pipeline stages. First, a tessellation control shader transforms control points of a patch and can produce per-patch data. Second, a fixed-function tessellator generates multiple primitives corresponding to a tessellation of the patch in (u,v) or (u,v,w) parameter space. Third, a tessellation evaluation shader transforms the vertices of the tessellated patch, for example to compute their positions and attributes as part of the tessellated surface. The tessellator is enabled when the pipeline contains both a tessellation control shader and a tessellation evaluation shader.

21.1. Tessellator

The type of subdivision performed by the tessellator is specified by an OpExecutionMode instruction in the tessellation evaluation or tessellation control shader using one of execution modes Triangles, Quads, and IsoLines. Other tessellation-related execution modes can also be specified in either the tessellation control or tessellation evaluation shaders, and if they ar= e specified in both then the modes must be = the same.

Tessellation execution modes include:

  • Triangles, Quads, and IsoLines. These control the type of subdivision and topology of the output primitives. One mode must be set in at least one of t= he tessellation shader stages.

  • VertexOrderCw and VertexOrderCcw. These control the orientation of triangles generated by the tessellator. One mode must be set in at least one of t= he tessellation shader stages.

  • PointMode. Controls generation of points rather than triangles or lines. This functionality defaults to disabled, and is enabled if either shader stage includes the execution mode.

  • SpacingEqual, SpacingFractionalEven, and SpacingFractionalOdd. Controls the spacing of segments on the edges of tessellated primitives. One mode must be set in at least one of t= he tessellation shader stages.

  • OutputVertices. Controls the size of the output patch of the tessellation control shader. One value must be set in at least one of = the tessellation shader stages.

For triangles, the tessellator subdivides a triangle primitive into smal= ler triangles. For quads, the tessellator subdivides a rectangle primitive into smaller triangles. For isolines, the tessellator subdivides a rectangle primitive into a collection of line segments arranged in strips stretching across the rectangle in the u dimension (i.e. the coordinate= s in TessCoord are of the form (0,x) through (1,x) for all tessellation evaluation shader invocations that share a line).

Each vertex produced by the tessellator has an associated (u,v,w) or (u,= v) position in a normalized parameter space, with parameter values in the rang= e [0,1], as illustrated in figures Domain parameterization for tessel= lation primitive modes (upper-left origin) and Domain parameterization for tessellation prim= itive modes (lower-left origin). The domain space can have either an upper= -left or lower-left origin, selected by the domainOrigin member of VkPipelineTessellationDo= mainOriginStateCreateInfo.

3D"tessparamUL"
Figure 22. Domain parameterization for tessellation pr= imitive modes (upper-left origin)
3D"tessparam"
Figure 23. Domain parameterization for tessellation pr= imitive modes (lower-left origin)
Caption

In the domain parameterization diagrams, the coordinates illustrate the value of TessCoord at the corners of the domain. The labels on the edges indicate the inner (IL0 and IL1) and outer (OL0 through OL3) tessellation level values used to control the number of subdivisions along each edge of the domain.

For triangles, the vertex=E2=80=99s position is a barycentric coordinate (u,v,w), where u + v + w =3D= 1.0, and indicates the relative influence of the three vertices of the triangle on the position of the vertex. For quads and isolines, the position is a (u,v) c= oordinate indicating the relative horizontal and vertical position of the vertex relative to the subdivided rectangle. The subdivision process is explained in more detail in subsequent sections.=

21.2. Tessellator Patch Discard

A patch is discarded by the tessellator if any relevant outer tessellati= on level is less than or equal to zero.

Patches will also be discarded if any relevant outer tessellation level corresponds to a floating-point NaN (not a number= ) in implementations supporting NaN.

No new primitives are generated and the tessellation evaluation shader i= s not executed for patches that are discarded. For Quads, all four outer levels are relevant. For Triangles and IsoLines, only the first three = or two outer levels, respectively, are relevant. Negative inner levels will not cause a patch to be discarded; they will be clamped as described below.

21.3. Tessellator Spacing

Each of the tessellation levels is used to determine the number and spac= ing of segments used to subdivide a corresponding edge. The method used to derive the number and spacing of segments is specified b= y an OpExecutionMode in the tessellation control or tessellation evaluation shader using one of the identifiers SpacingEqual, SpacingFractionalEven, or SpacingFractionalOdd.

If SpacingEqual is used, the floating-point tessellation le= vel is first clamped to [1, maxLevel], where maxLevel is the implementation-dependent maximum tessellation level (VkPhysicalDeviceLimits::maxTessellationGenerationLevel<= /code>). The result is rounded up to the nearest integer n= , and the corresponding edge is divided into n segments of = equal length in (u,v) space.

If SpacingFractionalEven is used, the tessellation level is= first clamped to [2, maxLevel] and then ro= unded up to the nearest even integer n. If SpacingFractionalOdd is used, the tessellation level is cla= mped to [1, maxLevel - 1] and then rounded u= p to the nearest odd integer n. If n is one, the edge will not be subdivided. Otherwise, the corresponding edge will be divided into n= - 2 segments of equal length, and two additional segments of equal length that are typically shorter than the other segments. The length of the two additional segments relative to the others will decrease monotonically with n - f, where f is the clamped floating-point tessellation level. When n - f is zero, the additional segments will = have equal length to the other segments. As n - f approaches 2.0, the relative length of t= he additional segments approaches zero. The two additional segments must be place= d symmetrically on opposite sides of the subdivided edge. The relative location of these two segments is implementation-dependent, bu= t must be identical for any pair of subdivi= ded edges with identical values of f.

When the tessellator produces triangles (in the Triangles o= r Quads modes), the orientation of all triangles is specified with an OpExecutionMode of VertexOrderCw or VertexO= rderCcw in the tessellation control or tessellation evaluation shaders. If the order is VertexOrderCw, the vertices of all generated t= riangles will have clockwise ordering in (u,v) or (u,v,w) space. If the order is VertexOrderCcw, the vertices will have counter-clockwise ordering.

If the tessellation domain has an upper-left origin, the vertices of a triangle have counter-clockwise ordering if

a =3D u0 v1 - u1 v0 + u1 v2 - u2 v1 + = u2 v0 - u0 v2

is negative, and clockwise ordering if a is po= sitive. ui and vi are the u and v coordinates in normalized parameter space of the ith vertex of t= he triangle. If the tessellation domain has a lower-left origin, the vertices of a triangle have counter-clockwise ordering if a is = positive, and clockwise ordering if a is negative.

Note

The value a is proportional (with a positive f= actor) to the signed area of the triangle.

In Triangles mode, even though the vertex coordinates have = a w value, it does not participate directly in the computation of a, being an affine combination of u and v.

For all primitive modes, the tessellator is capable of generating points instead of lines or triangles. If the tessellation control or tessellation evaluation shader specifies the OpExecutionMode PointMode, the primitive generato= r will generate one point for each distinct vertex produced by tessellation. Otherwise, the tessellator will produce a collection of line segments or triangles according to the primitive mode. When tessellating triangles or quads in point mode with fractional odd spacing, the tessellator may produce = interior vertices that are positioned on the edge of the patch if an inner tessellation level is less than or equal to one. Such vertices are considered distinct from vertices produced by subdividing the outer edge of the patch, even if there are pairs of vertices with identical coordinates.

21.4. Tessellation Primitive Orderi= ng

Few guarantees are provided for the relative ordering of primitives prod= uced by tessellation, as they pertain to primitive order.

  • The output primitives generated from each input primitive are passed to subsequent pipeline stages in an implementation-dependent order.

  • All output primitives generated from a given input primitive are passed to subsequent pipeline stages before any output primitives generated from subsequent input primitives.

21.5. Triangle Tessellation

If the tessellation primitive mode is Triangles, an equilat= eral triangle is subdivided into a collection of triangles covering the area of the original triangle. First, the original triangle is subdivided into a collection of concentric equilateral triangles. The edges of each of these triangles are subdivided, and the area between each triangle pair is filled by triangles produced by joining the vertices on the subdivided edges. The number of concentric triangles and the number of subdivisions along eac= h triangle except the outermost is derived from the first inner tessellation level. The edges of the outermost triangle are subdivided independently, using the first, second, and third outer tessellation levels to control the number of subdivisions of the u =3D 0 (left), v =3D 0 (bottom), and w =3D 0 (right) edges, respectively. The second inner tessellation level and the fourth outer tessellation level have no effect in this mode.

If the first inner tessellation level and all three outer tessellation levels are exactly one after clamping and rounding, only a single triangle with (u,v,w) coordinates of (0= ,0,1), (1,0,0), and (0,1,0) is generated. If the inner tessellation level is one and any of the outer tessellation levels is greater than one, the inner tessellation level is treated as though it were originally specified as 1 + =CE=B5 and will result in a two- or three-segment subdivision depending on the tessellation spacing. When used with fractional odd spacing, the three-segment subdivision may produce inner vertices positioned on the edge of the triangle.

If any tessellation level is greater than one, tessellation begins by producing a set of concentric inner triangles and subdividing their edges. First, the three outer edges are temporarily subdivided using the clamped and rounded first inner tessellation level and the specified tessellation spacing, generating n segments. For the outermost inner triangle, the inner triangle is degenerate=E2=80=89= =E2=80=94=E2=80=89a single point at the center of the triangle=E2=80=89=E2=80=94=E2=80=89if n is two. Otherwise, for each corner of the outer triangle, an inner triangle corner is produced at the intersection of two lines extended perpendicular to the corner=E2=80=99s two adjacent edges running through the vertex of the subdi= vided outer edge nearest that corner. If n is three, the edges of the inner triangle ar= e not subdivided and is the final triangle in the set of concentric triangles. Otherwise, each edge of the inner triangle is divided into n - 2 segments, with the n - 1 vertices of this subdivi= sion produced by intersecting the inner edge with lines perpendicular to the edge running through the n - 1 innermost vertices of the subdi= vision of the outer edge. Once the outermost inner triangle is subdivided, the previous subdivision process repeats itself, using the generated triangle as an outer triangle. This subdivision process is illustrated in Inner Triangle Tessellation.

3D"innertri"
Figure 24. Inner Triangle Tessellation
Caption

In the Inner Triangle Tessellation diagram, inner tessellation levels of (a) five and (b) four are shown (not to scale). Solid black circles depict vertices along the edges of the concentric triangles. The edges of inner triangles are subdivided by intersecting the edge with segments perpendicular to the edge passing through each inner vertex of the subdivided outer edge. Dotted lines depict edges connecting corresponding vertices on the inner an= d outer triangle edges.

Once all the concentric triangles are produced and their edges are subdivided, the area between each pair of adjacent inner triangles is fille= d completely with a set of non-overlapping triangles. In this subdivision, two of the three vertices of each triangle are taken from adjacent vertices on a subdivided edge of one triangle; the third is one of the vertices on the corresponding edge of the other triangle. If the innermost triangle is degenerate (i.e., a point), the triangle containing it is subdivided into six triangles by connecting each of the si= x vertices on that triangle with the center point. If the innermost triangle is not degenerate, that triangle is added to the set of generated triangles as-is.

After the area corresponding to any inner triangles is filled, the tessellator generates triangles to cover the area between the outermost triangle and the outermost inner triangle. To do this, the temporary subdivision of the outer triangle edge above is discarded. Instead, the u =3D 0, v =3D 0<= /span>, and w =3D 0 edges are subdivided according to the first, second, and third outer tessellation levels, respectively, and the tessellation spacing. The original subdivision of the first inner triangle is retained. The area between the outer and first inner triangles is completely filled b= y non-overlapping triangles as described above. If the first (and only) inner triangle is degenerate, a set of triangles is produced by connecting each vertex on the outer triangle edges with the center point.

After all triangles are generated, each vertex in the subdivided triangl= e is assigned a barycentric (u,v,w) coordinate based on its location relative to the three vertices of the outer triangle.

The algorithm used to subdivide the triangular domain in (u,v,w) space i= nto individual triangles is implementation-dependent. However, the set of triangles produced will completely cover the domain, an= d no portion of the domain will be covered by multiple triangles.

The order in which the vertices for a given output triangle is generated= is implementation-dependent. However, when depicted in a manner similar to Inner Triangle Tessellation, the order of the vertices in each generated triangle will= be either all clockwise or all counter-clockwise, according to the vertex orde= r layout declaration.

21.6. Quad Tessellation

If the tessellation primitive mode is Quads, a rectangle is= subdivided into a collection of triangles covering the area of the original rectangle. First, the original rectangle is subdivided into a regular mesh of rectangles, where the number of rectangles along the u = =3D 0 and u =3D 1 (vertical) and v =3D 0 and v =3D 1 (horizontal) edges are derived from the first and second inner tessellation levels, respectively. All rectangles, except those adjacent to one of the outer rectangle edges, are decomposed into triangle pairs. The outermost rectangle edges are subdivided independently, using the first= , second, third, and fourth outer tessellation levels to control the number o= f subdivisions of the u =3D 0 (left), v =3D 0 (bottom), u =3D 1 (right), and v =3D 1 (top) edges, respectively. The area between the inner rectangles of the mesh and the outer rectangle edges are filled by triangles produced by joining the vertices on the subdivided outer edges to the vertices on the edge of the inner rectangle mesh.

If both clamped inner tessellation levels and all four clamped outer tessellation levels are exactly one, only a single triangle pair covering the outer rectangle is generated. Otherwise, if either clamped inner tessellation level is one, that tessellation level is treated as though it were originally specified as 1 + =CE=B5 and will result in a two- or three-se= gment subdivision depending on the tessellation spacing. When used with fractional odd spacing, the three-segment subdivision may produce inner vertices positioned on the edge of the rectangle.

If any tessellation level is greater than one, tessellation begins by subdividing the u =3D 0 and u = =3D 1 edges of the outer rectangle into m segments using the clamped and rounded fir= st inner tessellation level and the tessellation spacing. The v =3D 0 and v =3D 1= edges are subdivided into n segments using the second inner tessellation level. Each vertex on the u =3D 0 and v =3D 0 edges are joined with the corresponding vertex on the u =3D 1 and v =3D 1 edges to produce a set of vertical and horizontal lines that divide the rectangle into a grid of smaller rectangles. The primitive generator emits a pair of non-overlapping triangles covering each such rectangle not adjacent to an edge of the outer rectangle. The boundary of the region covered by these triangles forms an inner rectangle, the edges of which are subdivided by the grid vertices that lie on the edge. If either m or n is two= , the inner rectangle is degenerate, and one or both of the rectangle=E2=80=99s edges consist of a single p= oint. This subdivision is illustrated in Figure Inner Quad Tessellation.

=3D"innerquad"
Figure 25. Inner Quad Tessellation
Caption

In the Inner Quad Tessellation diagram, inner quad tessellation levels of (a) (4,2) and (b) (7,4) are shown. The regions highlighted in red in figure (b) depict the 10 inner rectangles= , each of which will be subdivided into two triangles. Solid black circles depict vertices on the boundary of the outer and inner rectangles, where the inner rectangle on the top figure is degenerate (a single line segment). Dotted lines depict the horizontal and vertical edges connecting corresponding vertices on the inner and outer rectangle edges.

After the area corresponding to the inner rectangle is filled, the tessellator must produce triangles to cov= er the area between the inner and outer rectangles. To do this, the subdivision of the outer rectangle edge above is discarded. Instead, the u =3D 0, v =3D 0<= /span>, u =3D 1, and v =3D 1 edges are subdivided according to the first, second, third, and fourth outer tessellation levels, respectively, and the tessellation spacing. The original subdivision of the inner rectangle is retained. The area between the outer and inner rectangles is completely filled by non-overlapping triangles. Two of the three vertices of each triangle are adjacent vertices on a subdivided edge of one rectangle; the third is one of the vertices on the corresponding edge of the other triangle. If either edge of the innermost rectangle is degenerate, the area near the corresponding outer edges is filled by connecting each vertex on the outer edge with the single vertex making up the inner edge.

The algorithm used to subdivide the rectangular domain in (u,v) space in= to individual triangles is implementation-dependent. However, the set of triangles produced will completely cover the domain, an= d no portion of the domain will be covered by multiple triangles.

The order in which the vertices for a given output triangle is generated= is implementation-dependent. However, when depicted in a manner similar to Inner Quad Tessellation, the order of the vertices in each generated triangle will= be either all clockwise or all counter-clockwise, according to the vertex orde= r layout declaration.

21.7. Isoline Tessellation

If the tessellation primitive mode is IsoLines, a set of in= dependent horizontal line segments is drawn. The segments are arranged into connected strips called isolines, w= here the vertices of each isoline have a constant v coordinate and u coordinates covering the full range [0,1]. The number of isolines generated is derived from the first outer tessellation level; the number of segments in each isoline is derived from the second outer tessellation level. Both inner tessellation levels and the third and fourth outer tessellation levels have no effect in this mode.

As with quad tessellation above, isoline tessellation begins with a rectangle. The u =3D 0 and u =3D 1= edges of the rectangle are subdivided according to the first outer tessellation level. For the purposes of this subdivision, the tessellation spacing mode is ignored and treated as equal_spacing. An isoline is drawn connecting each vertex on the u =3D = 0 rectangle edge to the corresponding vertex on the u =3D 1 rectan= gle edge, except that no line is drawn between (0,1) and (1,1). If the number of isolines on the subdivided u =3D 0 and u =3D 1 edges is n, this process will result in n equally spaced lines with constant v coordinates of 0, \(\frac{1}{n}, \frac{2}{n}, \ldots, \frac{n-1}{n}\).

Each of the n isolines is then subdivided acco= rding to the second outer tessellation level and the tessellation spacing, resulting in m line segments. Each segment of each line is emitted by the tessellator.

The order in which the vertices for a given output line is generated is implementation-dependent.

21.8. Tessellation Pipeline State

The pTessellationState member of VkGraphicsPipelineCreateInfo points to a structure of type VkPipelineTessellationStateCreateInfo.

The VkPipelineTessellationStateCreateInfo structure is defi= ned as:

typedef struct VkPipelineTessel=
lationStateCreateInfo {
    VkStructureType                           sType;
    const void*                               pNext;
    VkPipelineTessellationStateCreateFlags    flags;
    uint32_t                                  patchControlPoints;
} VkPipelineTessellationStateCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • patchControlPoints number of control points per patch.

Valid Usage
  • patchControlPoints must be g= reater than zero and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSiz= e

Valid Usage (Implicit)
typedef VkFlags VkPipelineTessellationStateCreateFlags;=

VkPipelineTessellationStateCreateFlags is a bitmask type fo= r setting a mask, but is currently reserved for future use.

The possible tessellation domain origins are specified by the VkTessellationDomainOrigin enumeration:

typedef enum VkTessellationDoma=
inOrigin {
    VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT =3D 0<=
/span>,
    VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT =3D 1<=
/span>,
    VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR =3D VK_TESSELLATION_DOMAIN=
_ORIGIN_UPPER_LEFT,
    VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR =3D VK_TESSELLATION_DOMAIN=
_ORIGIN_LOWER_LEFT,
} VkTessellationDomainOrigin;

or the equivalent

typedef VkTessellationDomainOrigin VkTessellationDomainOriginK=
HR;

This enum affects how the VertexOrderCw and VertexOrd= erCcw tessellation execution modes are interpreted, since the winding is defined relative to the orientation of the domain.

22. Geometry Shading

The geometry shader operates on a group of vertices and their associated data assembled from a single input primitive, and emits zero or more output primitives and the group of vertices and their associated data required for each output primitive. Geometry shading is enabled when a geometry shader is included in the pipeline.

22.1. Geometry Shader Input Primitives

Each geometry shader invocation has access to all vertices in the primit= ive (and their associated data), which are presented to the shader as an array of inputs. The input primitive type expected by the geometry shader is specified with an OpExecutionMode instruction in the geometry shader, and must be compatible with the primitive topology used by primitive assembly (if tessellation is not in use) or must match= the type of primitive generated by the tessellation primitive generator (if tessellation is in use). Compatibility is defined below, with each input primitive type. The input primitive types accepted by a geometry shader are:

Points

Geometry shaders that operate on points use an OpExecutionMode instruction specifying the InputPoints input mode. Such a shader is valid only when the pipeline primitive topology is VK_PRIMITIVE_TOPOLOGY_POINT_LIST (if tessellation is not in us= e) or if tessellation is in use and the tessellation evaluation shader uses PointMode. There is only a single input vertex available for each geometry shader invocation. However, inputs to the geometry shader are still presented as an array, but this array has a length of one.

Lines

Geometry shaders that operate on line segments are generated by includin= g an OpExecutionMode instruction with the InputLines m= ode. Such a shader is valid only for the VK_PRIMITIVE_TOPOLOGY_LINE_LIST, and VK_PRIMITIVE_TOPOLOGY_LINE_STRIP primitive topologies (if tessellation is not in use) or if tessellation is in use and the tessellation mode is Isolines. There are two input vertices available for each geometry shader invocation. The first vertex refers to the vertex at the beginning of the line segment and the second vertex refers to the vertex at the end of the line segment.<= /p>

Lines with Adjacency

Geometry shaders that operate on line segments with adjacent vertices ar= e generated by including an OpExecutionMode instruction with the InputLinesAdjacency mode. Such a shader is valid only for the VK_PRIMITIVE_TOPOLOGY_LINES_WITH_ADJACENCY and VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY primitive topo= logies and must not be used when tessellation is= in use.

In this mode, there are four vertices available for each geometry shader invocation. The second vertex refers to attributes of the vertex at the beginning of th= e line segment and the third vertex refers to the vertex at the end of the line segment. The first and fourth vertices refer to the vertices adjacent to the beginning and end of the line segment, respectively.

Triangles

Geometry shaders that operate on triangles are created by including an OpExecutionMode instruction with the Triangles mo= de. Such a shader is valid when the pipeline topology is VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, or VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN (if tessellation is not in = use) or when tessellation is in use and the tessellation mode is Triangles or Quads.

In this mode, there are three vertices available for each geometry shade= r invocation. The first, second, and third vertices refer to attributes of the first, second, and third vertex of the triangle, respectively.

Triangles with Adjacency

Geometry shaders that operate on triangles with adjacent vertices are created by including an OpExecutionMode instruction with the InputTrianglesAdjacency mode. Such a shader is valid when the pipeline topology is VK_PRIMITIVE_TOPOLOGY_TRIANGLES_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, and must not be used when tessellation is in use.

In this mode, there are six vertices available for each geometry shader invocation. The first, third and fifth vertices refer to attributes of the first, secon= d and third vertex of the triangle, respectively. The second, fourth and sixth vertices refer to attributes of the vertices adjacent to the edges from the first to the second vertex, from the second to the third vertex, and from the third to the first vertex, respectively.<= /p>

22.2. Geometry Shader Output Primitives

A geometry shader generates primitives in one of three output modes: poi= nts, line strips, or triangle strips. The primitive mode is specified in the shader using an OpExecutionMod= e instruction with the OutputPoints, OutputLineStrip or OutputTriangleStrip modes, respectively. Each geometry shader must include exactly= one output primitive mode.

The vertices output by the geometry shader are assembled into points, li= nes, or triangles based on the output primitive type and the resulting primitive= s are then further processed as described in Rasterization. If the number of vertices emitted by the geometry shader is not sufficient to produce a single primitive, vertices corresponding to incomplete primitives are not processed by subsequent pipeline stages. The number of vertices output by the geometry shader is limited to a maximu= m count specified in the shader.

The maximum output vertex count is specified in the shader using an OpExecutionMode instruction with the mode set to OutputV= ertices and the maximum number of vertices that will be produced by the geometry shader specified as a literal. Each geometry shader must specify a maxim= um output vertex count.

22.3. Multiple Invocations of Geometry Shad= ers

Geometry shaders can be invoked more t= han one time for each input primitive. This is known as geometry shader instancing and is requested by in= cluding an OpExecutionMode instruction with mode specifie= d as Invocations and the number of invocations specified as an inte= ger literal.

In this mode, the geometry shader will execute at least n times for each input primitive, where n is the number of in= vocations specified in the OpExecutionMode instruction. The instance number is available to each invocation as a built-in input using InvocationId.

22.4. Geometry Shader Primitive Ordering

Limited guarantees are provided for the relative ordering of primitives produced by a geometry shader, as they pertain to = primitive order.

  • For instanced geometry shaders, the output primitives generated from each input primitive are passed to subsequent pipeline stages using the invocation number to order the primitives, from least to greatest.

  • All output primitives generated from a given input primitive are passed to subsequent pipeline stages before any output primitives generated from subsequent input primitives.

22.5. Geometry Shader Passthrough

A geometry shader that uses the PassthroughNV decoration on= a variable in its input interface is considered a passthrough geometry shader= . Output primitives in a passthrough geometry shader must have the same topology as the input primitive and are not produced by emitting vertices. The vertices of the output primitive have two different types of attributes= , per-vertex and per-primitive. Geometry shader input variables with PassthroughNV decoration = are considered to produce per-vertex outputs, where values for each output vertex are copied from the corresponding input vertex. Any built-in or user-defined geometry shader outputs are considered per-primitive in a passthrough geometry shader, where a single output value is copied to all output vertices.

The remainder of this section details the usage of the Passthrough= NV decoration and modifications to the interface matching rules when using passthrough geometry shaders.

22.5.1. PassthroughNV Decoration

Decorating a geometry shader input variable with the PassthroughNV= decoration indicates that values of this input are copied through to the corresponding vertex of the output primitive. Input variables and block members which do not have the PassthroughNV= decoration are consumed by the geometry shader without being passed through to subsequent stages.

The PassthroughNV decoration must<= /strong> only be used within a geometry shader.

Any variable decorated with PassthroughNV must be declared using the Input storage class.

The PassthroughNV decoration must<= /strong> not be used with any of:

  • an input primitive type other than InputPoints, Input= Lines, or Triangles, as specified by the mode for OpExecutionMode<= /code>.

  • an invocation count other than one, as specified by the Invocation= s mode for OpExecutionMode.

  • an OpEntryPoint which statically uses the OpEmitVerte= x or OpEndPrimitive instructions.

  • a variable decorated with the InvocationId built-in decorat= ion.

  • a variable decorated with the PrimitiveId built-in decorati= on that is declared using the Input storage class.

22.5.2. Passthrough Interface Mat= ching

When a passthrough geometry shader is in use, the Interface Matching rules involving th= e geometry shader input and output interfaces operate as described in this section.

For the purposes of matching passthrough geometry shader inputs with out= puts of the previous pipeline stages, the PassthroughNV decoration = is ignored.

For the purposes of matching the outputs of the geometry shader with subsequent pipeline stages, each input variable with the PassthroughN= V decoration is considered to add an equivalent output variable with the same type, decoration (other than PassthroughNV), number, and decla= ration order on the output interface. The output variable declaration corresponding to an input variable decorate= d with PassthroughNV will be identical to the input declaration,= except that the outermost array dimension of such variables is removed. The output block declaration corresponding to an input block decorated with PassthroughNV or having members decorated with Passthrou= ghNV will be identical to the input declaration, except that the outermost array dimension of such declaration is removed.

If an input block is decorated with PassthroughNV, the equi= valent output block contains all the members of the input block. Otherwise, the equivalent output block contains only those input block members decorated with PassthroughNV. All members of the corresponding output block are assigned Location and Component decorations identical to those assigned to the corre= sponding input block members.

Output variables and blocks generated from inputs decorated with PassthroughNV will only exist for the purposes of interface ma= tching; these declarations are not available to geometry shader code or listed in the module interface.

For the purposes of component counting, passthrough geometry shaders cou= nt all statically used input variable components declared with the PassthroughNV decoration as output components as well, since t= heir values will be copied to the output primitive produced by the geometry shader.

23. Fixed-Function Vertex Post-Processing

After programmable vertex processing, the following fixed-function operations are applied to vertices of the resulting primitives:

editing-note

TODO:Odd that this one link to a different chapter is in this list.

Next, rasterization is performed on primitives as described in chapter Rasterization.

23.1. Viewport Swizzle

Each primitive sent to a given viewport has a swizzle and optional negation applied to its clip coordinates. The swizzle that is applied depends on the viewport index, and is controlle= d by the VkPipelineViewportSwizzleStateCreateInfoNV pipeline sta= te:

typedef struct VkPipelineViewpo=
rtSwizzleStateCreateInfoNV {
    VkStructureType                                sType;
    const void*                                    pNext;
    VkPipelineViewportSwizzleStateCreateFlagsNV    flags;
    uint32_t                                       viewportCount;
    const VkViewportSwizzleNV*            =
         pViewportSwizzles;
} VkPipelineViewportSwizzleStateCreateInfoNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • viewportCount is the number of viewport swizzles used by th= e pipeline.

  • pViewportSwizzles is a pointer to an array of VkViewportSwizzleNV structures, defining the viewp= ort swizzles.

Valid Usage
  • viewportCount must match the= viewportCount set in VkPipelineViewportStateCreateInfo

Valid Usage (Implicit)
typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV;

VkPipelineViewportSwizzleStateCreateFlagsNV is a bitmask ty= pe for setting a mask, but is currently reserved for future use.

The VkPipelineViewportSwizzleStateCreateInfoNV state is set= by adding an instance of this structure to the pNext chain of an instanc= e of the VkPipelineViewportStateCreateInfo structure and setting the gr= aphics pipeline state with vkCreateGraphicsPipelines.

Each viewport specified from 0 to viewportCount - 1 has its= x,y,z,w swizzle state set to the corresponding x, y, z and w in the VkViewportSwizzleNV structure. Each component is of type VkViewportCoordina= teSwizzleNV, which determines the type of swizzle for that component. The value of x computes the new x component of the position as= :

if (x =3D=3D VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV) x' =3D x;
if (x =3D=3D VK_VIEWPORT_COORDINATE_SWIZZLE_=
NEGATIVE_X_NV) x' =3D -x;
if (x =3D=3D VK_VIEWPORT_COORDINATE_SWIZZLE_=
POSITIVE_Y_NV) x' =3D y;
if (x =3D=3D VK_VIEWPORT_COORDINATE_SWIZZLE_=
NEGATIVE_Y_NV) x' =3D -y;
if (x =3D=3D VK_VIEWPORT_COORDINATE_SWIZZLE_=
POSITIVE_Z_NV) x' =3D z;
if (x =3D=3D VK_VIEWPORT_COORDINATE_SWIZZLE_=
NEGATIVE_Z_NV) x' =3D -z;
if (x =3D=3D VK_VIEWPORT_COORDINATE_SWIZZLE_=
POSITIVE_W_NV) x' =3D w;
if (x =3D=3D VK_VIEWPORT_COORDINATE_SWIZZLE_=
NEGATIVE_W_NV) x' =3D -w;

Similar selections are performed for the y, z,= and w coordinates. This swizzling is applied before clipping and perspective divide. If the swizzle for an active viewport index is not specified, the swizzle for x is VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, y is VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV, z is VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV and w is VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV.

Viewport swizzle parameters are specified by setting the pNext pointer of VkGraphicsPipelineCreateInfo to point to an instance of VkPipelineViewportSwizzleStateCreateInfoNV. VkPipelineViewportSwizzleStateC= reateInfoNV uses VkViewportSwizzleNV to set the viewport swizzle parameters.

The VkViewportSwizzleNV structure is defined as:

typedef struct VkViewportSwizzl=
eNV {
    VkViewportCoordinateSwizzleNV    x;
    VkViewportCoordinateSwizzleNV    y;
    VkViewportCoordinateSwizzleNV    z;
    VkViewportCoordinateSwizzleNV    w;
} VkViewportSwizzleNV;
Valid Usage (Implicit)

Possible values of the VkViewportSwizzleNV::x, y, z, and w members, specifying swizzling of the corresponding compo= nents of primitives, are:

typedef enum VkViewportCoordina=
teSwizzleNV {
    VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV =3D 0,
    VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV =3D 1,
    VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV =3D 2,
    VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV =3D 3,
    VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV =3D 4,
    VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV =3D 5,
    VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV =3D 6,
    VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV =3D 7,
} VkViewportCoordinateSwizzleNV;

These values are described in detail in Viewport Swizzle.

23.2. Flat Shading

Flat shading a vertex output attribute means to assign all vert= ices of the primitive the same value for that output.

The output values assigned are those of the provoking vertex of= the primitive. The provoking vertex depends on the primitive topology, and is generally th= e =E2=80=9Cfirst=E2=80=9D vertex of the primitive. For primitives not processed by tessellation or geometry shaders, the provoking vertex is selected from the input vertices according to the following table.

Table 31. Provoking vertex selection

Pri= mitive type of primitive i

Pro= voking vertex number

VK_PRIMITIVE_TOPOLOGY_POINT_LIST

i

VK_PRIMITIVE_TOPOLOGY_LINE_LIST

2 i

VK_PRIMITIVE_TOPOLOGY_LINE_STRIP

i

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST

3 i

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP

i

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN

i + 1

VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY

4 i + 1

VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY

i + 1

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY

6 i

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY

2 i

Caption

The Provoking vertex selection table def= ines the output values used for flat shading the ith primitive genera= ted by drawing commands with the indicated primitive type, derived from the corresponding values of the vertex whose index is shown in the table. Primitives and vertices are numbered starting from zero.

Flat shading is applied to those vertex attributes that match fragment input attributes which are decorated as Flat.

If a geometry shader is active, the output primitive topology is either points, line strips, or triangle strips, and the selection of the provoking vertex behaves according to the corresponding row of the table. If a tessellation evaluation shader is active and a geometry shader is not active, the provoking vertex is undefined but must= be one of the vertices of the primitive.

23.3. Primitive Clipping

Primitives are culled against the cull volume and then clipped = to the clip volume. In clip coordinates, the view volume is defined by:

\[\begin{array}{c} -w_c \leq x_c \leq w_c \\ -w_c \leq y_c \leq w_c \\ 0 \leq z_c \leq w_c \end{array}\]

This view volume can be further restri= cted by as many as VkPhysicalDeviceLimits::maxClipDistances client-d= efined half-spaces.

The cull volume is the intersection of up to VkPhysicalDeviceLimits::maxCullDistances client-d= efined half-spaces (if no client-defined cull half-spaces are enabled, culling against the cull volume is skipped).

A shader must write a single cull dist= ance for each enabled cull half-space to elements of the CullDistance array. If the cull distance for any enabled cull half-space is negative for all of the vertices of the primitive under consideration, the primitive is discarded. Otherwise the primitive is clipped against the clip volume as defined below= .

The clip volume is the intersection of up to VkPhysicalDeviceLimits::maxClipDistances client-d= efined half-spaces with the view volume (if no client-defined clip half-spaces are enabled, the clip volume is the view volume).

A shader must write a single clip dist= ance for each enabled clip half-space to elements of the ClipDistance array. Clip half-space i is then given by the set of poi= nts satisfying the inequality

ci(P) =E2=89=A5 0<= /p>

where ci(P) is the= clip distance i at point P. For point primitives, ci(P)<= /span> is simply the clip distance for the vertex in question. For line and triangle primitives, per-vertex clip distances are interpolate= d using a weighted mean, with weights derived according to the algorithms described in sections Basic Line Segment Rasterization and Basic Polygon Rasterization, using the perspective interpolation equations.

The number of client-defined clip and cull half-spaces that are enabled = is determined by the explicit size of the built-in arrays ClipDistance and CullDistance, respectively, declared as an output in the inter= face of the entry point of the final shader stage before clipping.

Depth clamping is enabled or disabled via the depthClampEnable enable of the VkPipelineRasterizationStateCreateInfo structure. If depth clamping is enabled, the plane equation

0 =E2=89=A4 zc =E2=89=A4 wc

(see the clip volume definition above) is ignored by view volume clippin= g (effectively, there is no near or far plane clipping).

If the primitive under consideration is a point or line segment, then clipping passes it unchanged if its vertices lie entirely within the clip volume.

Possible values of VkPhysicalDevicePointClippingPrope= rties::pointClippingBehavior, specifying clipping behavior of a point primitive whose vertex lies outside the clip volume, are:

typedef enum VkPointClippingBeh=
avior {
    VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES =3D =
0,
    VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY =3D 1,
    VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR =3D VK_POINT_CLIPPING_BE=
HAVIOR_ALL_CLIP_PLANES,
    VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR =3D VK_POINT_CLIPP=
ING_BEHAVIOR_USER_CLIP_PLANES_ONLY,
} VkPointClippingBehavior;

or the equivalent

typedef VkPointClippingBehavior VkPointClippingBehaviorKHR;
  • VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES specifies that t= he primitive is discarded if the vertex lies outside any clip plane, including the planes bounding the view volume.

  • VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY specifies = that the primitive is discarded only if the vertex lies outside any user clip plane.

If either of a line segment=E2=80=99s vertices lie outside of the clip v= olume, the line segment may be clipped, with new ver= tex coordinates computed for each vertex that lies outside the clip volume. A clipped line segment endpoint lies on both the original line segment and the boundary of the clip volume.

This clipping produces a value, 0 =E2=89=A4 t =E2=89= =A4 1, for each clipped vertex. If the coordinates of a clipped vertex are P and the original vertices=E2=80=99 coordinates are P1 and P2, then t is given by

P =3D t P1 + (1-t) P2.

editing-note

This is weird - it gives P, not t.

t is used to clip vertex output attributes as = described in Clipping Shader Outputs.

If the primitive is a polygon, it passes unchanged if every one of its e= dges lie entirely inside the clip volume, and it is discarded if every one of it= s edges lie entirely outside the clip volume. If the edges of the polygon intersect the boundary of the clip volume, the intersecting edges are reconnected by new edges that lie along the boundary of the clip volume - in some cases requiring the introduction of new vertices into a polygon.

If a polygon intersects an edge of the clip volume=E2=80=99s boundary, t= he clipped polygon must include a point on this boun= dary edge.

Primitives rendered with user-defined half-spaces must satisfy a complementarity criterion. Suppose a series of primitives is drawn where each vertex i has a single specified clip distance di (or = a number of similarly specified clip distances, if multiple half-spaces are enabled). Next, suppose that the same series of primitives are drawn again with each such clip distance replaced by -di (an= d the graphics pipeline is otherwise the same). In this case, primitives must not be miss= ing any pixels, and pixels must not be drawn twice in regions where those primitives are cut by the clip planes.

23.4. Clipping Shader Out= puts

Next, vertex output attributes are clipped. The output values associated with a vertex that lies within the clip volume are unaffected by clipping. If a primitive is clipped, however, the output values assigned to vertices produced by clipping are clipped.

Let the output values assigned to the two vertices P1 and P2 of an unclipped ed= ge be c1 and c2. The value of t (see Prim= itive Clipping) for a clipped point P is used to= obtain the output value associated with P as

c =3D t c1 + (1-t) c2.

(Multiplying an output value by a scalar means multiplying each of x= , y, z, and w by the scalar.)

Since this computation is performed in clip space before division by wc, clipped output values are perspect= ive-correct.

Polygon clipping creates a clipped vertex along an edge of the clip volu= me=E2=80=99s boundary. This situation is handled by noting that polygon clipping proceeds by clipping against one half-space at a time. Output value clipping is done in the same way, so that clipped points alway= s occur at the intersection of polygon edges (possibly already clipped) with the clip volume=E2=80=99s boundary.

For vertex output attributes whose matching fragment input attributes ar= e decorated with NoPerspective, the value of = t used to obtain the output value associated with P w= ill be adjusted to produce results that vary linearly in framebuffer space.

Output attributes of integer or unsigned integer type must always be flat shaded. Flat shaded attributes are constant over the primitive being rasterized (se= e Basic Line Segment Rasterization and Basic Polygon Rasterization), and no interpolation is performed. The output value c is taken from= either c1 or c2, since flat shadin= g has already occurred and the two values are identical.

23.5. Controlling Viewport W Sca= ling

If viewport W scaling is enabled, the W component of the clip coordinate is modified by the provided coefficients from the corresponding viewport as follows.

wc' =3D xcoeff xc + = ycoeff yc + wc

The VkPipelineViewportWScalingStateCreateInfoNV structure i= s defined as:

typedef struct VkPipelineViewpo=
rtWScalingStateCreateInfoNV {
    VkStructureType                sType;
    const void*                    pNext;
    VkBool32                       viewportWScalingEnable;
    uint32_t                       viewportCount;
    const VkViewportWScalingNV*    pViewpo=
rtWScalings;
} VkPipelineViewportWScalingStateCreateInfoNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • viewportWScalingEnable controls whether viewport W<= /strong> scaling is enabled.

  • viewportCount is the number of viewports used by W<= /strong> scaling, and must match the number of viewports in the= pipeline if viewport W scaling is enabled.

  • pViewportWScalings is a pointer to an array of VkViewportWScalingNV structures, which define the W scaling parameters for the corresponding viewport. If the viewport W scaling state is dynamic, this member is= ignored.

Valid Usage (Implicit)

The VkPipelineViewportWScalingStateCreateInfoNV state is se= t by adding an instance of this structure to the pNext chain of an instanc= e of the VkPipelineViewportStateCreateInfo structure and setting the gr= aphics pipeline state with vkCreateGraphicsPipelines.

If the bound pipeline state object was not created with the VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV dynamic state enabled, = viewport W scaling parameters are specified using the pViewpo= rtWScalings member of VkPipelineViewportWS= calingStateCreateInfoNV in the pipeline state object. If the pipeline state object was created with the VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV dynamic state enabled, = the viewport transformation parameters are dynamically set and changed with the command:

void vkCmdSetViewportWScalingNV(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstViewport,
    uint32_t                                    viewportCount,
    const VkViewportWScalingNV*           =
      pViewportWScalings);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • firstViewport is the index of the first viewport whose para= meters are updated by the command.

  • viewportCount is the number of viewports whose parameters a= re updated by the command.

  • pViewportWScalings is a pointer to an array of VkViewportWScalingNV structures specifying viewpo= rt parameters.

The viewport parameters taken from element i o= f pViewportWScalings replace the current state for the viewport = index firstViewport + i, for i in [0, viewportCount).

Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV dynamic state enabled

  • firstViewport must be less t= han VkPhysicalDeviceLimits::maxViewports

  • The sum of firstViewport and viewportCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive

Valid Usage (Implicit)
Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

Both VkPipelineViewportWSca= lingStateCreateInfoNV and vkCmdSetViewportWScalingNV use VkView= portWScalingNV to set the viewport transformation parameters.

The VkViewportWScalingNV structure is defined as:

typedef struct VkViewportWScali=
ngNV {
    float    xcoeff;
    float    ycoeff;
} VkViewportWScalingNV;
  • xcoeff and ycoeff are the viewport=E2=80=99s W= scaling factor for x and y respectively.

23.6. Coordinate Transformations<= /h3>

Clip coordinates for a vertex result from shader execution, whi= ch yields a vertex coordinate Position.

Perspective division on clip coordinates yields normalized device coordinates, followed by a viewport transformation (see Controlling the Viewport) to convert these coordinates into framebuffer coordinates.

If a vertex in clip coordinates has a position given by

\[\left(\begin{array}{c} x_c \\ y_c \\ z_c \\ w_c \end{array}\right)\]

then the vertex=E2=80=99s normalized device coordinates are

\[\left( \begin{array}{c} x_d \\ y_d \\ z_d \end{array} \right) =3D \left( \begin{array}{c} \frac{x_c}{w_c} \\ \frac{y_c}{w_c} \\ \frac{z_c}{w_c} \end{array} \right)\]

23.7. Controlling the Viewport

The viewport transformation is determined by the selected viewport=E2=80= =99s width and height in pixels, px and py, respectively, and its center (ox, oy) (also in pi= xels), as well as its depth range min and max determining a depth range scale value pz and a depth range bias value oz (defined below). The vertex=E2=80=99s framebuffer coordinates (xf, yf, zf) are given by

xf =3D (px / 2) xd += ox

yf =3D (py / 2) yd += oy

zf =3D pz =C3=97 zd = + oz

Multiple viewports are available, numbered zero up to VkPhysicalDeviceLimits::maxViewports minus one. The number of viewports used by a pipeline is controlled by the viewportCount member of the VkPipelineViewportStateCreat= eInfo structure used in pipeline creation.

The VkPipelineViewportStateCreateInfo structure is defined = as:

typedef struct VkPipelineViewpo=
rtStateCreateInfo {
    VkStructureType                       sType;
    const void*                           pNext;
    VkPipelineViewportStateCreateFlags    flags;
    uint32_t                              viewportCount;
    const VkViewport*                     =
pViewports;
    uint32_t                              scissorCount;
    const VkRect2D*                       =
pScissors;
} VkPipelineViewportStateCreateInfo;
Valid Usage
Valid Usage (Implicit)
  • = sType must be VK_STRUCTURE_T= YPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO

  • Each <= code>pNext member of any structure (including this one) in the pNext chain must be either = NULL or a pointer to a valid instance of VkPipelineViewportSwizzleStateCreateInfoNV or VkPipelineViewportWScalingStateCreate= InfoNV

  • Each = sType member in the pNext chain must be unique

  • = flags must be 0=

  • viewportCount must b= e greater than 0

  • scissorCount must be = greater than 0

typedef VkFlags VkPipelineViewportStateCreateFlags;

VkPipelineViewportStateCreateFlags is a bitmask type for se= tting a mask, but is currently reserved for future use.

A vertex processing stage may direct each primitive to zero or = more viewports. The destination viewports for a primitive are selected by the last active vertex processing stage that has an output variable decorated with ViewportIndex (selecting a single viewport) or ViewportM= askNV (selecting multiple viewports). The viewport transform uses the viewport corresponding to either the value assigned to ViewportIndex or one of the bits set in ViewportMaskNV, and taken from an implementation-dependent ver= tex of each primitive. If ViewportIndex or any of the bits in ViewportMaskNV are outside the range zero to viewportCount minus one for a primitive, or = if the last active vertex processing stage did not assign a value to either ViewportIndex or ViewportMaskNV for all vertices = of a primitive due to flow control, the results of the viewport transformation of the vertices of such primitives are undefined. If the last vertex processing stage does not have an output decorated with ViewportIndex or ViewportMaskNV, the viewport num= bered zero is used by the viewport transformation.

A single vertex can be used in more th= an one individual primitive, in primitives such as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP. In this case, the viewport transformation is applied separately for each primitive.

If the bound pipeline state object was not created with the VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled, viewport transformation parameters are specified using the pViewports m= ember of VkPipelineViewportStateCreateInfo in the pipeline state object= . If the pipeline state object was created with the VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled, the viewport transformation parameters are dynamically set and changed with the command:=

void vkCmdSetViewport(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstViewport,
    uint32_t                                    viewportCount,
    const VkViewport*                     =
      pViewports);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • firstViewport is the index of the first viewport whose para= meters are updated by the command.

  • viewportCount is the number of viewports whose parameters a= re updated by the command.

  • pViewports is a pointer to an array of VkViewpo= rt structures specifying viewport parameters.

The viewport parameters taken from element i o= f pViewports replace the current state for the viewport index f= irstViewport + i, for i in [0, viewportCount).

Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled

  • firstViewport must be less t= han VkPhysicalDeviceLimits::maxViewports

  • The sum of firstViewport and viewportCount must be between 1 and VkPhysicalDeviceLimits::maxViewports<= /code>, inclusive

  • If the multiple viewports feature is not enabled, firstViewport must be 0

  • If the multiple viewports feature is not enabled, viewportCount must be 1

Valid Usage (Implicit)
  • comma= ndBuffer must be a valid VkC= ommandBuffer handle

  • pViewpor= ts must be a valid pointer to an a= rray of viewportCount valid VkViewport structures=

  • comma= ndBuffer must be in the recording state

  • The VkC= ommandPool that commandBuffer was allocated from must support graphics operations

  • vie= wportCount must be greater than 0

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

Both VkPipelineViewportStateCreateInf= o and vkCmdSetViewport use VkViewport to set the viewport transformation parameters.

The VkViewport structure is defined as:

typedef struct VkViewport {
    float    x;
    float    y;
    float    width;
    float    height;
    float    minDepth;
    float    maxDepth;
} VkViewport;
  • x and y are the viewport=E2=80=99s upper left = corner (x,y).

  • width and height are the viewport=E2=80=99s wi= dth and height, respectively.

  • minDepth and maxDepth are the depth range for = the viewport. It is valid for minDepth to be greater than or equal to maxDepth.

The framebuffer depth coordinate zf= may be represented using either a fixed-point or floating-point representation. However, a floating-point representation must be used if the depth/stencil attachment has a floating-point depth component. If an m-bit fixed-point representation is used, w= e assume that it represents each value \(\frac{k}{2^m - 1}\), where k =E2= =88=88 { 0, 1, =E2=80=A6=E2=80=8B, 2m-1 }, as k= (e.g. 1.0 is represented in binary as a string of all ones).

The viewport parameters shown in the above equations are found from thes= e values as

ox =3D x + width / 2

oy =3D y + height / 2

oz =3D minDepth

px =3D width

py =3D height

pz =3D maxDepth - minDe= pth.

The application can specify a negative= term for height, which has the effect of negating the y coordinate in clip space before performing the transform. When using a negative height, the application should also adjust the y value to point to the lower left corner of the viewport inst= ead of the upper left corner. Using the negative height allows the application to avoid havi= ng to negate the y component of the Position output from the last ve= rtex processing stage in shaders that also target other graphics APIs.

The width and height of the imple= mentation-dependent maximum viewport dimensions must be greater than or equal to the width and height of the largest image which can be created and attached to a framebuffer.

The floating-point viewport bounds are represented with an implementation-dependent precision.

Valid Usage
  • width must be greater than <= code>0.0

  • width must be less than or e= qual to VkPhysicalDeviceLimits::maxViewportDimensions[0]<= /p>

  • The absolute value of height must be less than or equal to VkPhysicalDeviceLimits::maxViewportDimensions[1]<= /p>

  • x must be greater than or eq= ual to viewportBoundsRange[0]

  • (x + width) must be less than or equal to viewportBoundsRange[1]

  • y must be greater than or eq= ual to viewportBoundsRange[0]

  • y must be less than or equal= to viewportBoundsRange[1]

  • (y + height) must be greater than or equal to viewportBoundsRange[0]

  • (y + height) must be less than or equal to viewportBoundsRange[1]

  • Unless VK_EXT_depth_range_unrestrict= ed extension is enabled minDepth must be between 0.0 and 1.0, inclusive

  • Unless VK_EXT_depth_range_unrestrict= ed extension is enabled maxDepth must be between 0.0 and 1.0, inclusive

24. Rasterization

Rasterization is the process by which a primitive is converted to a two-dimensional image. Each point of this image contains associated data such as depth, color, or other attributes.

Rasterizing a primitive begins by determining which squares of an intege= r grid in framebuffer coordinates are occupied by the primitive, and assignin= g one or more depth values to each such square. This process is described below for points, lines, and polygons.

A grid square, including its (x,y) framebuffer= coordinates, z (depth), and associated data added by fragment shaders, is called a fragment. A fragment is located by its upper left corner, which lies on integer grid coordinates.

Rasterization operations also refer to a fragment=E2=80=99s sample locat= ions, which are offset by subpixel fractional values from its upper left corner. The rasterization rules for points, lines, and triangles involve testing whether each sample location is inside the primitive. Fragments need not actually be square, and rasterization rules are not affected by the aspect ratio of fragments. Display of non-square grids, however, will cause rasterized points and line segments to appear fatter in one direction than the other.

We assume that fragments are square, since it simplifies antialiasing an= d texturing. After rasterization, fragments are processed by the early per-fragment tests, if enabled.

Several factors affect rasterization, including the members of VkPipelineRasterizationStateCreateInfo and VkPipelineMultisampleStateCreateInfo.

The VkPipelineRasterizationStateCreateInfo structure is def= ined as:

typedef struct VkPipelineRaster=
izationStateCreateInfo {
    VkStructureType                            sType;
    const void*                                pNext;
    VkPipelineRasterizationStateCreateFlags    flags;
    VkBool32                                   depthClampEnable;
    VkBool32                                   rasterizerDiscardEnable;
    VkPolygonMode                              polygonMode;
    VkCullModeFlags                            cullMode;
    VkFrontFace                                frontFace;
    VkBool32                                   depthBiasEnable;
    float                           =
           depthBiasConstantFactor;
    float                           =
           depthBiasClamp;
    float                           =
           depthBiasSlopeFactor;
    float                           =
           lineWidth;
} VkPipelineRasterizationStateCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • depthClampEnable controls whether to clamp the fragment=E2= =80=99s depth values instead of clipping primitives to the z planes of the frustum, as described in Primitive Clipping.

  • rasterizerDiscardEnable controls whether primitives are dis= carded immediately before the rasterization stage.

  • polygonMode is the triangle rendering mode. See VkPolygonMode.

  • cullMode is the triangle facing direction used for primitiv= e culling. See VkCullModeFlagBits.

  • frontFace is a VkFrontFace value specifyin= g the front-facing triangle orientation to be used for culling.

  • depthBiasEnable controls whether to bias fragment depth val= ues.

  • depthBiasConstantFactor is a scalar factor controlling the constant depth value added to each fragment.

  • depthBiasClamp is the maximum (or minimum) depth bias of a fragment.

  • depthBiasSlopeFactor is a scalar factor applied to a fragme= nt=E2=80=99s slope in depth bias calculations.

  • lineWidth is the width of rasterized line segments.

The application can also add a VkPipelineRasterizationStateRasterizationOrderAMD structure to= the pNext chain of a VkPipelineRasterizationStateCreateInfo<= /code> structure. This structure enables selecting the rasterization order to use when rendering with the corresponding graphics pipeline as described in Rasterization Order.

Valid Usage
  • If the depth clamping feature is not enabled, depthClampEnable must be VK_FALSE

  • = If the non-solid fill modes feature is not enabled, polygonMode m= ust be VK_POLYGON_MODE_FILL or VK_POLYGON_MODE_FILL_RECTANGLE_N= V

  • = If the VK_NV_fill_rectangle extensio= n is not enabled, polygonMode must not be VK_POLYGON_MODE_FILL_RECTANGLE_NV

Valid Usage (Implicit)
typedef VkFlags VkPipelineRasterizationStateCreateFlags;

VkPipelineRasterizationStateCreateFlags is a bitmask type f= or setting a mask, but is currently reserved for future use.

The VkPipelineMultisampleStateCreateInfo structure is defin= ed as:

typedef struct VkPipelineMultis=
ampleStateCreateInfo {
    VkStructureType                          sType;
    const void*                              pNext;
    VkPipelineMultisampleStateCreateFlags    flags;
    VkSampleCountFlagBits                    rasterizationSamples;
    VkBool32                                 sampleShadingEnable;
    float                           =
         minSampleShading;
    const VkSampleMask*                   =
   pSampleMask;
    VkBool32                                 alphaToCoverageEnable;
    VkBool32                                 alphaToOneEnable;
} VkPipelineMultisampleStateCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • rasterizationSamples is a VkSampleCo= untFlagBits specifying the number of samples per pixel used in rasterization.

  • sampleShadingEnable can b= e used to enable Sample Shading.

  • minSampleShading specifies a minimum fraction of sample sha= ding if sampleShadingEnable is set to VK_TRUE.

  • pSampleMask is a bitmask of static coverage information tha= t is ANDed with the coverage information generated during rasterization, as described in Sample Mask.

  • alphaToCoverageEnable controls whether a temporary coverage= value is generated based on the alpha component of the fragment=E2=80=99s first c= olor output as specified in the Multisample Coverage section.

  • alphaToOneEnable controls whether the alpha component of th= e fragment=E2=80=99s first color output is replaced with one as described in Multisample Coverage.

Valid Usage
  • If the sample rate shading feature is not enabled, sampleShadingEnable must be VK_FALSE

  • If the alpha to one feature is not enabled, alphaToOneEnable must be VK_FALSE

  • minSampleShading must be in = the range [0,1]

  • If the subpass has any color attachments and rasterizationSamples is greater than the number of color samples, then sampleShadingEnable must be = VK_FALSE

Valid Usage (Implicit)
  • sType must be VK_STRUCTUR= E_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO

  • Eac= h pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkPipelineCoverageModulationStateCreateInfoNV, <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kPipelineCoverageToColorStateCreateInfoNV">VkPipelineCoverageToColorStateCr= eateInfoNV, or VkPipelineS= ampleLocationsStateCreateInfoEXT

  • Ea= ch sType member in the pNext chain must be unique

  • flags must be 0

  • rasterizationSamples = must be a valid VkSampleCountFlagBits v= alue

  • If pSampleMask is not NULL, pSampleM= ask must be a valid pointer to an = array of \(\lceil{\mathit{rasterizationSamples} \over 32}\rceil\) VkS= ampleMask values

typedef VkFlags VkPipelineMultisampleStateCreateFlags;<=
/pre>

VkPipelineMultisampleStateCreateFlags is a bitmask type for= setting a mask, but is currently reserved for future use.

Rasterization only produces fragments corresponding to pixels in the framebuffer. Fragments which would be produced by application of any of the primitive rasterization rules described below but which lie outside the framebuffer are not produced, nor are they processed by any later stage of the pipeline= , including any of the early per-fragment tests described in Early Per-Fragment Tests.

Surviving fragments are processed by fragment shaders. Fragment shaders determine associated data for fragments, and can also modify or replace their assigned depth values.

If the subpass for which this pipeline is being created uses color and/o= r depth/stencil attachments, then rasterizationSamples must be the same as the maximum of the sample counts of those subpass attachments.

If the subpass for which this pipeline is being created does not use col= or or depth/stencil attachments, rasterizationSamples must follow the rules for a zero-attachment subpass.

24.1. Discarding Primitives Before Rasterizati= on

Primitives are discarded before rasterization if the rasterizerDiscardEnable member of VkPipelineRasterizationStateCreateI= nfo is enabled. When enabled, primitives are discarded after they are processed by the last active shader stage in the pipeline before rasterization.

24.2. Rasterization Order

Within a subpass of a render pass instance, for a given (x,y,layer,sample) sample location, the following operations are guaranteed to execute in rasterization order, for each separate primitive tha= t includes that sample location:

Each of these operations is atomically executed for each primitive and sample location.

Execution of these operations for each primitive in a subpass occurs in an order determined by the application.

The rasterization order to use for a graphics pipeline is specified by adding a VkPipelineRasterizationStateRasterizationOrderAMD str= ucture to the pNext chain of a

The VkPipelineRasterizationStateRasterizationOrderAMD struc= ture is defined as:

typedef struct VkPipelineRaster=
izationStateRasterizationOrderAMD {
    VkStructureType            sType;
    const void*                pNext;
    VkRasterizationOrderAMD    rasterizationOrder;
} VkPipelineRasterizationStateRasterizationOrderAMD;
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD

  • rasterizationOrder must be a valid VkRasterizationO= rderAMD value

If the VK_AMD_rasterization_order<= /code> device extension is not enabled or the application does not request a particular rasterization order through specifying a VkPipelineRasterizationStateRasterizationOrderAMD structure then the rasterization order used by the graphics pipeline defaults to VK_RASTERIZATION_ORDER_STRICT_AMD.

Possible values of VkPipelineRasterizationS= tateRasterizationOrderAMD::rasterizationOrder, specifying the primitive rasterization order, are:

typedef enum VkRasterizationOrd=
erAMD {
    VK_RASTERIZATION_ORDER_STRICT_AMD =3D 0,
    VK_RASTERIZATION_ORDER_RELAXED_AMD =3D 1=
,
} VkRasterizationOrderAMD;
  • VK_RASTERIZATION_ORDER_STRICT_AMD specifies that operations= for each primitive in a subpass must occur in= primitive order.

  • VK_RASTERIZATION_ORDER_RELAXED_AMD specifies that operation= s for each primitive in a subpass may not occur= in primitive order.

24.3. Multisampling

Multisampling is a mechanism to antialias all Vulkan primitives: points, lines, and polygons. The technique is to sample all primitives multiple times at each pixel. Each sample in each framebuffer attachment has storage for a color, depth, and/or stencil value, such that per-fragment operations apply to each sampl= e independently. The color sample values can be later = resolved to a single color (see Resolving Multisample Images and the Render Pass chapter for more details on how to resolve multisample images to non-multisample images).

Vulkan defines rasterization rules for single-sample modes in a way that= is equivalent to a multisample mode with a single sample in the center of each pixel.

Each fragment includes a coverage value with rasterizationSamples<= /code> bits (see Sample Mask). Each fragment includes rasterizationSamples depth values and s= ets of associated data. An implementation may choose to assign th= e same associated data to more than one sample. The location for evaluating such associated data m= ay be anywhere within the pixel including the pixel center or any of the sample locations. When rasterizationSamples is VK_SAMPLE_COUNT_1_BIT, the pixel center must be used. The different associated data values need not all be evaluated at the same location. Each pixel fragment thus consists of integer x and y grid coordinates, rasterizationSamples depth values and sets of associated data,= and a coverage value with rasterizationSamples bits.

It is understood that each pixel has rasterizationSamples l= ocations associated with it. These locations are exact positions, rather than regions or areas, and each is referred to as a sample point. The sample points associated with a pixel must be located inside or on the boundary of the unit square that is considered to bound the pixel. Furthermore, the relative locations of sample points may be identical for each pixel in the framebuffer, or they may differ. If the current pipeline includes a fragment shader with one or more variables in its interface decorated with Sample and Inp= ut, the data associated with those variables will be assigned independently for eac= h sample. The values for each sample must be evalua= ted at the location of the sample. The data associated with any other variables not decorated with Sampl= e and Input need not be evaluated independently for each sample.=

If the standardSampleLocations member of VkPhysicalDeviceLimits is VK_TRUE, then the sample counts VK_SAMPLE_COUNT_1_BIT= , VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT, and VK_SAMPLE_COUNT_16_BIT= have sample locations as listed in the following table, with the ith entry in the table corresponding to bit i in the sample ma= sks. VK_SAMPLE_COUNT_32_BIT and VK_SAMPLE_COUNT_64_BIT= do not have standard sample locations. Locations are defined relative to an origin in the upper left corner of the pixel.

Table 32. Standard sample locations

VK_SAMPLE_COUNT_1_BIT

VK_SAMPLE_COUNT_2_BIT

VK_SAMPLE_COUNT_4_BIT

VK_SAMPLE_COUNT_8_BIT

VK_SAMPLE_COUNT_16_BIT

(0.5,0.5)

(0.75,0.75)
(0.25,0.25)

(0.375, 0.125)
(0.875, 0.375)
(0.125, 0.625)
(0.625, 0.875)

(0.5625, 0.3125)
(0.4375, 0.6875)
(0.8125, 0.5625)
(0.3125, 0.1875)
(0.1875, 0.8125)
(0.0625, 0.4375)
(0.6875, 0.9375)
(0.9375, 0.0625)

(0.5625, 0.5625)
(0.4375, 0.3125)
(0.3125, 0.625)
(0.75, 0.4375)
(0.1875, 0.375)
(0.625, 0.8125)
(0.8125, 0.6875)
(0.6875, 0.1875)
(0.375, 0.875)
(0.5, 0.0625)
(0.25, 0.125)
(0.125, 0.75)
(0.0, 0.5)
(0.9375, 0.25)
(0.875, 0.9375)
(0.0625, 0.0)

Color images created with multiple samples per pixel use a compression technique where there are two arrays of data associated with each pixel. The first array contains one element per sample where each element stores a= n index to the second array defining the fragment mask of the pixel. The second array contains one element per color fragment and each = element stores a unique color value in the format of the image. With this compression technique it=E2=80=99s not always necessary to actual= ly use unique storage locations for each color sample: when multiple samples share the same color value the fragment mask may have two samples referring to the same color fragment. The number of color fragments is determined by the samples mem= ber of the VkImageCreateInfo structure used to create the i= mage. The VK_AMD_shader_fragment_mask device extension provides shader instructions enabling the application to get direct access to the fragment mask and the individual color fragment values.

3D"fragment
Figure 26. Fragment Mask

24.4. Custom Sample Locations

Applications can also control the samp= le locations used for rasterization.

If the pNext chain of the VkPipelineMultisampleStateCreateInfo structure specified at pipeline creation time includes an instance of the VkPipelineSampleLocationsStateCreateInfoEXT structure, then th= at structure controls the sample locations used when rasterizing primitives with the pipeline.

The VkPipelineSampleLocationsStateCreateInfoEXT structure i= s defined as:

typedef struct VkPipelineSample=
LocationsStateCreateInfoEXT {
    VkStructureType             sType;
    const void*                 pNext;
    VkBool32                    sampleLocationsEnable;
    VkSampleLocationsInfoEXT    sampleLocationsInfo;
} VkPipelineSampleLocationsStateCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • sampleLocationsEnable controls whether custom sample locati= ons are used. If sampleLocationsEnable is VK_FALSE, the default= sample locations are used and the values specified in sampleLocationsInfo are ignored.

  • sampleLocationsInfo is the sample locations to use during rasterization if sampleLocationsEnable is VK_TRUE= and the graphics pipeline is not created with VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT.

Valid Usage (Implicit)

The VkSampleLocationsInfoEXT structure is defined as:

typedef struct VkSampleLocation=
sInfoEXT {
    VkStructureType               sType;
    const void*                   pNext;
    VkSampleCountFlagBits         sampleLocationsPerPixel;
    VkExtent2D                    sampleLocationGridSize;
    uint32_t                      sampleLocationsCount;
    const VkSampleLocationEXT*    pSampleL=
ocations;
} VkSampleLocationsInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • sampleLocationsPerPixel is a VkSampl= eCountFlagBits specifying the number of sample locations per pixel.

  • sampleLocationGridSize is the size of the sample location g= rid to select custom sample locations for.

  • sampleLocationsCount is the number of sample locations in pSampleLocations.

  • pSampleLocations is an array of sampleLocationsCount<= /code> VkSampleLocationEXT structures.

This structure can be used either to s= pecify the sample locations to be used for rendering or to specify the set of sample locations an image subresource has been last rendered with for the purposes of layout transitions of depth/stencil images created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT.

The sample locations in pSampleLocations specify sampleLocationsPerPixel number of sample locations for each pi= xel in the grid of the size specified in sampleLocationGridSize. The sample location for sample i at the pixel gri= d location (x,y) is taken from pSam= pleLocations[(x + y * sampleLocationGridSize.width) * sampleLocationsPerPixel + i].

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_SAMPL= E_LOCATIONS_INFO_EXT

  • sampleLocationsPerPixel must be a valid VkSampleCountFlagBits value

  • = pSampleLocations must be a v= alid pointer to an array of sampleLocationsCount VkSampl= eLocationEXT structures

  • sampleLocationsCount must be greater than 0

The VkSampleLocationEXT structure is defined as:

typedef struct VkSampleLocation=
EXT {
    float    x;
    float    y;
} VkSampleLocationEXT;
  • x is the horizontal coordinate of the sample=E2=80=99s loca= tion.

  • y is the vertical coordinate of the sample=E2=80=99s locati= on.

The domain space of the sample location coordinates has an upper-left or= igin within the pixel in framebuffer space.

The values specified in a VkSampleLocationEXT structure are= always clamped to the implementation-dependent sample location coordinate range [sampleLocationCoordinateRange[0],sam= pleLocationCoordinateRange[1]] that can be queried by chaining the VkPhysicalDeviceSampleLocatio= nsPropertiesEXT structure to the pNext chain of VkPhysicalDevicePr= operties2.

The custom sample locations used for rasterization when VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocat= ionsEnable is VK_TRUE are specified by the VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocat= ionsInfo property of the bound graphics pipeline, if the pipeline was not created with VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT enabled.

Otherwise, the sample locations used for rasterization are set by callin= g vkCmdSetSampleLocationsEXT:

void vkCmdSetSampleLocationsEXT(
    VkCommandBuffer                             commandBuffer,
    const VkSampleLocationsInfoEXT*       =
      pSampleLocationsInfo);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • pSampleLocationsInfo is the sample locations state to set.<= /p>

Valid Usage
Valid Usage (Implicit)
  • <= code>commandBuffer must be a valid= VkCommandBuffer handle

  • pSampleLocationsInfo must be a valid pointer to a valid VkSampleLocationsInfoEXT str= ucture

  • <= code>commandBuffer must be in the = recording state

  • The= VkCommandPool that commandBuffer was allocated f= rom must support graphics operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

24.6. Points

A point is drawn by generating a set of fragments in the shape of a squa= re centered around the vertex of the point. Each vertex has an associated point size that controls the width/height of that square. The point size is taken from the (potentially clipped) shader built-in PointSize written by:

  • the geometry shader, if active;

  • the tessellation evaluation shader, if active and no geometry shader is active;

  • the vertex shader, otherwise

and clamped to the implementation-dependent point size range [pointSizeRange[0],pointSizeRange[1]]. If the value written to PointSize is less than or equal to zer= o, or if no value was written to PointSize, results are undefined.

Not all point sizes need be supported, but the size 1.0 must be supported. The range of supported sizes and the size of evenly-spaced gradations withi= n that range are implementation-dependent. The range and gradations are obtained from the pointSizeRange = and pointSizeGranularity members of VkPhys= icalDeviceLimits. If, for instance, the size range is from 0.1 to 2.0 and the gradation size is 0.1, then the size 0.1, 0.2, =E2=80=A6=E2=80=8B, 1.9, 2.0 are supported. Additional point sizes may also be suppor= ted. There is no requirement that these sizes be equally spaced. If an unsupported size is requested, the nearest supported size is used instead.

24.6.1. Basic Point Rasterization

Point rasterization produces a fragment for each framebuffer pixel with = one or more sample points that intersect a region centered at the point=E2=80= =99s (xf,yf). This region is a square with side equal to the current point size. Coverage bits that correspond to sample points that intersect the region ar= e 1, other coverage bits are 0.

All fragments produced in rasterizing a point are assigned the same associated data, which are those of the vertex corresponding to the point. However, the fragment shader built-in PointCoord contains poin= t sprite texture coordinates. The s and t point sprit= e texture coordinates vary from zero to one across the point horizontally left-to-right and top-to-bottom, respectively. The following formulas are used to evaluate s and= t:

\[s =3D {1 \over 2} + { \left( x_p - x_f \right) \over \text{size} }\]
\[t =3D {1 \over 2} + { \left( y_p - y_f \right) \over \text{size} }\]

where size is the point=E2=80=99s size, (xp,yp) is the location at which the point sprite coordinates are evaluated - this = may be the framebuffer coordinates of the pixel center (i.e. at the half-integer) or the location of a sample, and (xf,yf) is= the exact, unrounded framebuffer coordinate of the vertex for the point. When rasterizationSamples is VK_SAMPLE_COUNT_1_BIT, the pixel center must be used.

24.7. Line Segments

A line is drawn by generating a set of fragments overlapping a rectangle centered on the line segment. Each line segment has an associated width that controls the width of that rectangle.

The line width is specified by the VkPipelineRasterizationStateCreateI= nfo::lineWidth property of the currently active pipeline, if the pipeline was not created with VK_DYNAMIC_STATE_LINE_WIDTH enabled.

Otherwise, the line width is set by calling vkCmdSetLineWidth:

void vkCmdSetLineWidth(
    VkCommandBuffer                             commandBuffer,
    float                           =
            lineWidth);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • lineWidth is the width of rasterized line segments.

Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled

  • If the wide lines feature is not enabled, lineWidth must be <= code>1.0

Valid Usage (Implicit)
  • comm= andBuffer must be a valid Vk= CommandBuffer handle

  • comm= andBuffer must be in the recording state

  • The Vk= CommandPool that commandBuffer was allocated from must support graphics operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

Not all line widths need be supported for line segment rasterization, bu= t width 1.0 antialiased segments must be pr= ovided. The range and gradations are obtained from the lineWidthRange = and lineWidthGranularity members of VkPhys= icalDeviceLimits. If, for instance, the size range is from 0.1 to 2.0 and the gradation size is 0.1, then the size 0.1, 0.2, =E2=80=A6=E2=80=8B, 1.9, 2.0 are supported. Additional line widths may also be suppor= ted. There is no requirement that these widths be equally spaced. If an unsupported width is requested, the nearest supported width is used instead.

24.7.1. Basic Line Segment Rasterization

Rasterized line segments produce fragments which intersect a rectangle centered on the line segment. Two of the edges are parallel to the specified line segment; each is at a distance of one-half the current width from that segment in directions perpendicular to the direction of the line. The other two edges pass through the line endpoints and are perpendicular t= o the direction of the specified line segment. Coverage bits that correspond to sample points that intersect the rectangle are 1, other coverage bits are 0.

Next we specify how the data associated with each rasterized fragment ar= e obtained. Let pr =3D (xd, y= d) be the framebuffer coordinates at which associated data are evaluated. This may be the pixel center of a fragmen= t or the location of a sample within the fragment. When rasterizationSamples is VK_SAMPLE_COUNT_1_BIT, the pixel center must be used. Let pa =3D (xa, y= a) and pb = =3D (xb,yb) be initial and final endpoints of the line segment, respectively. Set

\[t =3D {{( \mathbf{p}_r - \mathbf{p}_a ) \cdot ( \mathbf{p}_b - \mathbf{p}= _a )} \over {\| \mathbf{p}_b - \mathbf{p}_a \|^2 }}\]

(Note that t =3D 0 at p_a and t =3D 1 at pb. Also note that this calculation projects the vector from pa to pr onto the line, and= thus computes the normalized distance of the fragment along the line.)

The value of an associated datum f for the fra= gment, whether it be a shader output or the clip w coordinate, must be determined using perspective interpolation:

\[f =3D {{ (1-t) {f_a / w_a} + t { f_b / w_b} } \over {(1-t) / w_a + t / w_b }}\]

where fa and fb are the data associated with the starting and ending endpoints of the segment, respectively; wa and wb are the clip w coordinates of the starting and en= ding endpoints of the segments, respectively.

Depth values for lines must be determi= ned using linear interpolation:

z =3D (1 - t) za + t zb=

where za and zb are the depth values of the starting and ending endpoints of the segment, respectively.

The NoPerspective and Flat interpolation decorations can be used with fragment shader inputs to declare how they are interpolated. When neither decoration is applied, perspec= tive interpolation is performed as described above. When the NoPerspective decoration is used, linear interpolation is performed in the same fashion as for de= pth values, as described above. When the Flat decoration is used, no interpolation is performe= d, and outputs are taken from the corresponding input value of the provoking vertex corresponding to that primitive.

The above description documents the preferred method of line rasterizati= on, and must be used when the implementation = advertises the strictLines limit in VkPhysicalDeviceLimits as VK_TRU= E.

When strictLines is VK_FALSE, the edges of the= lines are generated as a parallelogram surrounding the original line. The major axis is chosen by noting the axis in which there is the greatest distance between the line start and end points. If the difference is equal in both directions then the X axis is chosen as the major axis. Edges 2 and 3 are aligned to the minor axis and are centered on the endpoints of the line as in Non strict lines, and= each is lineWidth long. Edges 0 and 1 are parallel to the line and connect the endpoints of edges 2 and 3. Coverage bits that correspond to sample points that intersect the parallelogram are 1, other coverage bits are 0.

Samples that fall exactly on the edge of the parallelogram follow the polygon rasterization rules.

Interpolation occurs as if the parallelogram was decomposed into two triangles where each pair of vertices at each end of the line has identical attributes.

3D"non
Figure 27. Non strict lines

24.8. Polygons

A polygon results from the decomposition of a triangle strip, triangle f= an or a series of independent triangles. Like points and line segments, polygon rasterization is controlled by several variables in the VkPipeline= RasterizationStateCreateInfo structure.

24.8.1. Basic Polygon Rasterization

The first step of polygon rasterization is to determine whether the tria= ngle is back-facing or front-facing. This determination is made based on the sign of the (clipped or unclipped) polygon=E2=80=99s area computed in framebuffer coordinates. One way to compute this area is:

\[a =3D -{1 \over 2}\sum_{i=3D0}^{n-1} x_f^i y_f^{i \oplus 1} - x_f^{i \oplus 1} y_f^i\]

where \(x_f^i\) and \(y_f^i\) are the x and y framebuffer coordinates of the ith vertex of the = n-vertex polygon (vertices are numbered starting at zero for the purposes of this computation) and i =E2=8A=95 1 is (i + 1) mod n.

The interpretation of the sign of a is determi= ned by the VkPipelineRasterizationStateCreateI= nfo::frontFace property of the currently active pipeline. Possible values are:

typedef enum VkFrontFace {
    VK_FRONT_FACE_COUNTER_CLOCKWISE =3D 0,
    VK_FRONT_FACE_CLOCKWISE =3D 1,
} VkFrontFace;
  • VK_FRONT_FACE_COUNTER_CLOCKWISE specifies that a triangle w= ith positive area is considered front-facing.

  • VK_FRONT_FACE_CLOCKWISE specifies that a triangle with nega= tive area is considered front-facing.

Any triangle which is not front-facing is back-facing, including zero-ar= ea triangles.

Once the orientation of triangles is determined, they are culled accordi= ng to the VkPipelineRasterizationState= CreateInfo::cullMode property of the currently active pipeline. Possible values are:

typedef enum VkCullModeFlagBits=
 {
    VK_CULL_MODE_NONE =3D 0,
    VK_CULL_MODE_FRONT_BIT =3D 0x00000001,
    VK_CULL_MODE_BACK_BIT =3D 0x00000002,
    VK_CULL_MODE_FRONT_AND_BACK =3D 0x00000003,
} VkCullModeFlagBits;
  • VK_CULL_MODE_NONE specifies that no triangles are discarded=

  • VK_CULL_MODE_FRONT_BIT specifies that front-facing triangle= s are discarded

  • VK_CULL_MODE_BACK_BIT specifies that back-facing triangles = are discarded

  • VK_CULL_MODE_FRONT_AND_BACK specifies that all triangles ar= e discarded.

Following culling, fragments are produced for any triangles which have n= ot been discarded.

typedef VkFlags VkCullModeFlags;

VkCullModeFlags is a bitmask type for setting a mask of zer= o or more VkCullModeFlagBits.

The rule for determining which fragments are produced by polygon rasterization is called point sampling. The two-dimensional projection obtained by taking the x and y framebuffer coordinates of the polygon=E2=80=99s vertices is formed. Fragments are produced for any pixels for which any sample points lie insid= e of this polygon. Coverage bits that correspond to sample points that satisfy the point sampling criteria are 1, other coverage bits are 0. Special treatment is given to a sample whose sample location lies on a polygon edge. In such a case, if two polygons lie on either side of a common edge (with identical endpoints) on which a sample point lies, then exactly one of the polygons must result in a covered sample = for that fragment during rasterization. As for the data associated with each fragment produced by rasterizing a polygon, we begin by specifying how these values are produced for fragments in a triangle. Define barycentric coordinates for a triangle. Barycentric coordinates are a set of three numbers, a, b, and c, each in the range [0,1], with a + b + c =3D 1. These coordinates uniquely specify any point p wi= thin the triangle or on the triangle=E2=80=99s boundary as

p =3D a pa + b pb + c pc=

where pa, p= b, and pc are the vertice= s of the triangle. a, b, and c are determined by:

\[a =3D {{\mathrm{A}(p p_b p_c)} \over {\mathrm{A}(p_a p_b p_c)}}, \quad b =3D {{\mathrm{A}(p p_a p_c)} \over {\mathrm{A}(p_a p_b p_c)}}, \quad c =3D {{\mathrm{A}(p p_a p_b)} \over {\mathrm{A}(p_a p_b p_c)}},\]

where A(lmn) denotes the area in framebuffer c= oordinates of the triangle with vertices l, m, and n.

Denote an associated datum at pa, <= span class=3D"eq">pb, or pc= as fa, fb, or fc, respectively.

The value of an associated datum f for a fragm= ent produced by rasterizing a triangle, whether it be a shader output or the clip w coordinate, must be determined using pers= pective interpolation:

\[f =3D { a {f_a / w_a} + b {f_b / w_b} + c {f_c / w_c} } \over { {a / w_a} + {b / w_b} + {c / w_c} }\]

where wa, w= b, and wc are the clip w coordinates of pa, = pb, and pc, respecti= vely. a, b, and c are the barycentric coordinates of the location at which the data are produced - this mus= t be a pixel center or the location of a sample. When rasterizationSamples is VK_SAMPLE_COUNT_1_BIT, the pixel center must be used.

Depth values for triangles must be det= ermined using linear interpolation:

z =3D a za + b zb + c zc=

where za, z= b, and zc are the depth v= alues of pa, pb, and pc, respectively.

The NoPerspective and Flat interpolation decorations can be used with fragment shader inputs to declare how they are interpolated. When neither decoration is applied, per= spective interpolation is performed as described above. When the NoPerspective decoration is used, linear interpolation is performed in the same fashion as for depth values, as described above. When the Flat decoration is used, no interpolation is performe= d, and outputs are taken from the corresponding input value of the provoking vertex corresponding to that primitive.

When the VK_AMD_shader_ex= plicit_vertex_parameter device extension is enabled the CustomInterpAMD interpolation decoration can also be= used with fragment shader inputs which indicate that the decorated inputs can only be accessed by the extended instruction InterpolateAtVertexAMD and allows accessi= ng the value of the inputs for individual vertices of the primitive.

For a polygon with more than three edges, such as are produced by clippi= ng a triangle, a convex combination of the values of the datum at the polygon=E2= =80=99s vertices must be used to obtain the value= assigned to each fragment produced by the rasterization algorithm. That is, it must be the case that at ever= y fragment

\[f =3D \sum_{i=3D1}^{n} a_i f_i\]

where n is the number of vertices in the polyg= on and fi is the value of f at vertex i. For each i, 0 =E2=89=A4 a= i =E2=89=A4 1 and \(\sum_{i=3D1}^{n}a_i =3D 1\). The values of ai may differ from fragment to fragment, but at vertex i, ai =3D 1<= /span> and aj =3D 0 for j =E2=89=A0 i.

Note

One algorithm that achieves the required behavior is to triangulate a polygon (without adding any vertices) and then treat each triangle individually as already discussed. A scan-line rasterizer that linearly interpolates data along each edge and then linearly interpolates data across each horizontal span from edge to edge also satisfies the restrictions (in this case, the numerator and denominator of equation [triangle_persp= ective_interpolation] are iterated independently and a division performed for each fragment).

24.8.2. Polygon Mode

Possible values of the VkPipelineRasterizationStateCreateI= nfo::polygonMode property of the currently active pipeline, specifying the method of rasterization for polygons, are:

typedef enum VkPolygonMode {
    VK_POLYGON_MODE_FILL =3D 0,
    VK_POLYGON_MODE_LINE =3D 1,
    VK_POLYGON_MODE_POINT =3D 2,
    VK_POLYGON_MODE_FILL_RECTANGLE_NV =3D 100015300=
0,
} VkPolygonMode;
  • VK_POLYGON_MODE_POINT specifies that polygon vertices are d= rawn as points.

  • VK_POLYGON_MODE_LINE specifies that polygon edges are drawn= as line segments.

  • VK_POLYGON_MODE_FILL specifies that polygons are rendered u= sing the polygon rasterization rules in this section.

  • VK_POLYGON_MODE_FILL_RECTANGLE_NV specifies that polygons a= re rendered using polygon rasterization rules, modified to consider a sample within the primitive if the sample location is inside the axis-aligned bounding box of the triangle after projection. Note that the barycentric weights used in attribute interpolation can extend outside the range [0,1] when these primiti= ves are shaded. Special treatment is given to a sample position on the boundary edge of the bounding box. In such a case, if two rectangles lie on either side of a common edge (with identical endpoints) on which a sample position lies, then exactly one of the triangles must produce a fragm= ent that covers that sample during rasterization.

    Polygons rendered in VK_POLYGON_MODE_FILL_RECTANGLE_NV mode= may be clipped by the frustum or by user clip planes. If clipping is applied, the triangle is culled rather than clipped.

    Area calculation and facingness are determined for VK_POLYGON_MODE_FILL_RECTANGLE_NV mode using the triangle= =E2=80=99s vertices.

These modes affect only the final rasterization of polygons: in particul= ar, a polygon=E2=80=99s vertices are shaded and the polygon is clipped and poss= ibly culled before these modes are applied.

24.8.3. Depth Bias

The depth values of all fragments generated by the rasterization of a polygon can be offset by a single value t= hat is computed for that polygon. This behavior is controlled by the depthBiasEnable, depthBiasConstantFactor, depthBiasClamp, and depthBiasSlopeFactor members of VkPipelineRasterizationStateCreateI= nfo, or by the corresponding parameters to the vkCmdSetDepthBias command if depth bias stat= e is dynamic.

void vkCmdSetDepthBias(
    VkCommandBuffer                             commandBuffer,
    float                           =
            depthBiasConstantFactor,
    float                           =
            depthBiasClamp,
    float                           =
            depthBiasSlopeFactor);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • depthBiasConstantFactor is a scalar factor controlling the constant depth value added to each fragment.

  • depthBiasClamp is the maximum (or minimum) depth bias of a fragment.

  • depthBiasSlopeFactor is a scalar factor applied to a fragme= nt=E2=80=99s slope in depth bias calculations.

If depthBiasEnable is VK_FALSE, no depth bias = is applied and the fragment=E2=80=99s depth values are unchanged.

depthBiasSlopeFactor scales the maximum depth slope of the = polygon, and depthBiasConstantFactor scales an implementation-dependent constant that relates to the usable resolution of the depth buffer. The resulting values are summed to produce the depth bias value which is then clamped to a minimum or maximum value specified by depthBiasClamp. depthBiasSlopeFactor, depthBiasConstantFactor, an= d depthBiasClamp can each be p= ositive, negative, or zero.

The maximum depth slope m of a triangle is

\[m =3D \sqrt{ \left({{\partial z_f} \over {\partial x_f}}\right)^2 + \left({{\partial z_f} \over {\partial y_f}}\right)^2}\]

where (xf, yf, zf) is a point on the triangle. m may be approx= imated as

\[m =3D \max\left( \left| { {\partial z_f} \over {\partial x_f} } \right|, \left| { {\partial z_f} \over {\partial y_f} } \right| \right).\]

The minimum resolvable difference r is an impl= ementation-dependent parameter that depends on the depth buffer representation. It is the smallest difference in framebuffer coordinate = z values that is guaranteed to remain distinct throughout polygon rasterization and in th= e depth buffer. All pairs of fragments generated by the rasterization of two polygons with otherwise identical vertices, but zf values that differ by r, will have distinct depth values.

For fixed-point depth buffer representations, r is constant throughout the range of the entire depth buffer. For floating-point depth buffers, there is no single minimum resolvable difference. In this case, the minimum resolvable difference for a given polygon is dependent on the maximum exponent, e, in the rang= e of z values spanned by the primitive. If n is the number of bits in the floating-point = mantissa, the minimum resolvable difference, r, for the given primitive= is defined as

r =3D 2e-n

If a triangle is rasterized using the VK_POLYGON_MODE_FILL_RECTANGLE_NV polygon mode, then this mini= mum resolvable difference may not be resolvab= le for samples outside of the triangle, where the depth is extrapolated.

If no depth buffer is present, r is undefined.=

The bias value o for a polygon is

\[o =3D \begin{cases} m \times depthBiasSlopeFactor + r \times depthBiasConstantFactor & depthBiasClamp =3D 0\ or\ = NaN \\ \min(m \times depthBiasSlopeFactor + r \times depthBiasConstantFactor, depthBiasClamp) & depthBiasClamp > 0 \\ \max(m \times depthBiasSlopeFactor + r \times depthBiasConstantFactor, depthBiasClamp) & depthBiasClamp < 0 \\ \end{cases}\]

m is computed as described above. If the depth buffer uses a fixed-point representation, m= is a function of depth values in the range [0,1], and o is applied to depth values in the same range.

For fixed-point depth buffers, fragment depth values are always limited = to the range [0,1] by clamping after depth bias addi= tion is performed. Unless the VK_EXT_depth_range_unrest= ricted extension is enabled, fragment depth values are clamped even when the depth buffer uses a floating-point representation.

Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled

  • If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0

Valid Usage (Implicit)
  • comm= andBuffer must be a valid Vk= CommandBuffer handle

  • comm= andBuffer must be in the recording state

  • The Vk= CommandPool that commandBuffer was allocated from must support graphics operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

24.8.4. Conservative Rasterization<= /h4>

Polygon rasterization can be made cons= ervative by setting conservativeRasterizationMode to VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT or VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT in VkPipelineRasterizationConservativeStateCreateInfoEXT. The VkPipelineRasterizationConservativeStateCreateInfoEXT stat= e is set by adding an instance of this structure to the pNext chain of = an instance of the VkPipelineRasterizationStateCreateInfo structu= re when creating the graphics pipeline. Enabling these modes also affects line and point rasterization if the implementation sets VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= conservativePointAndLineRasterization to VK_TRUE.

VkPipelineRasterizationConservativeStateCreateInfoEXT is de= fined as:

typedef struct VkPipelineRaster=
izationConservativeStateCreateInfoEXT {
    VkStructureType                                           sType;
    const void*                                               pNext;
    VkPipelineRasterizationConservativeStateCreateFlagsEXT    flags;
    VkConservativeRasterizationModeEXT                        conservativeR=
asterizationMode;
    float                           =
                          extraPrimitiveOverestimationSize;
} VkPipelineRasterizationConservativeStateCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • conservativeRasterizationMode is the conservative rasteriza= tion mode to use.

  • extraPrimitiveOverestimationSize is the extra size in pixel= s to increase the generating primitive during conservative rasterization at each of its edges in X and Y equally in screen sp= ace beyond the base overestimation specified in VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= primitiveOverestimationSize.

Valid Usage
  • extraPrimitiveOverestimationSize must= be in the range of 0.0 to VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= maxExtraPrimitiveOverestimationSize inclusive

Valid Usage (Implicit)
  • sType must be = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_IN= FO_EXT

  • flags must be 0

  • conservativeRasterizationMo= de must be a valid VkConservativeRasterizationModeEXT value

typedef VkFlags VkPipelineRasterizationConservativeStateCreate=
FlagsEXT;

VkPipelineRasterizationConservativeStateCreateFlagsEXT is a= bitmask type for setting a mask, but is currently reserved for future use.

Possible values of VkPipelineRasterizat= ionConservativeStateCreateInfoEXT::conservativeRasterizationMode<= /code>, specifying the conservative rasterization mode are:

typedef enum VkConservativeRast=
erizationModeEXT {
    VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT =3D 0,
    VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT =3D 1,
    VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT =3D 2,
} VkConservativeRasterizationModeEXT;
  • VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT specifies t= hat conservative rasterization is disabled and rasterization proceeds as normal.

  • VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT specifi= es that conservative rasterization is enabled in overestimation mode.

  • VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT specif= ies that conservative rasterization is enabled in underestimation mode.

When overestimate conservative rasterization is enabled, rather than evaluating coverage at individual sample locations, a determination is made of whether any portion of the pixel (including its edges and corners) is covered by the primitive. If any portion of the pixel is covered, then all bits of the coverage sampl= e mask for the fragment are enabled. If the implementation supports VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= conservativeRasterizationPostDepthCoverage and the PostDepthCoverage execution mode is specified the SampleMask built-in input vari= able will reflect the coverage after the early per-fragment depth and stencil tests are applied.

For the purposes of evaluating which pixels are covered by the primitive= , implementations can increase the size of = the primitive by up to VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= primitiveOverestimationSize pixels at each of the primitive edges. This may increase the number of fragments= generated by this primitive and represents an overestimation of the pixel coverage.

This overestimation size can be increased further by setting the extraPrimitiveOverestimationSize value above 0.0 = in steps of VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= extraPrimitiveOverestimationSizeGranularity up to and including VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= extraPrimitiveOverestimationSize. This will: further increase the number of fragments generated by this primitive.

The actual precision of the overestimation size used for conservative rasterization may vary between implementa= tions and produce results that only approximate the primitiveOverestimationSize and extraPrimitiveOverestimationSizeGranularity properties.

For triangles if VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_E= XT is enabled, fragments will be generated if the primitive area covers any portion of the pixel, including its edges or corners. The tie-breaking rule described in Basic Polygon Rasterization does not apply during conservative rasterization and coverage is set for all fragments generated from shared edges of polygons. Degenerate triangles that evaluate to zero area after rasterization, even for pixels that contain a vertex or edge of the zero-area polygon, will be culled if VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= degenerateTrianglesRasterized is VK_FALSE or will generate fragments if degenerateTrianglesRasterized is VK_TRUE. The fragment input values for these degenerate triangles take their attribute and depth values from the provoking vertex. Degenerate triangles are considered backfacing and the application can enable backface culling if desired. Triangles that are zero area before rasterization = may be culled regardless.

For lines if VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT is enabled, and the implementation sets VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= conservativePointAndLineRasterization to VK_TRUE, fragments will be generated if the line covers any= portion of the pixel, including its edges or corners. Degenerate lines that evaluate to zero length after rasterization will be culled if VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= degenerateLinesRasterized is VK_FALSE or will generate fragments if degenerateLinesRasterized is VK_TRUE. The fragments input values for these degenerate lines take their attribute and depth values from the provoking vertex. Lines that are zero length before rasterization ma= y be culled regardless.

For points if VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT<= /code> is enabled, and the implementation sets VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= conservativePointAndLineRasterization to VK_TRUE, fragments will be generated if the point square co= vers any portion of the pixel square, including its edges or corners.

When underestimate conservative rasterization is enabled, rather than evaluating coverage at individual sample locations, a determination is made of whether all of the pixel (including its edges and corners) is covered by the primitive. If the entire pixel is covered, then a fragment is generated with all bits of its coverage sample mask enabled, otherwise the fragment is discarded even if some portion of the pixel is covered. If the implementation supports VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= conservativeRasterizationPostDepthCoverage and the PostDepthCoverage execution mode is specified the SampleMask built-in input vari= able will reflect the coverage after the early per-fragment depth and stencil tests are applied.

For triangles, if VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE= _EXT is enabled, fragments will only be generated if they are fully covered by the generating primitive, including its edges and corners.

For lines, if VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT= is enabled, fragments will be generated if the entire pixel, including its edges and corners is covered by the line.

For points, if VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EX= T is enabled, fragments will only be generated for pixel squares that are fully covered by the point square.

For both overestimate and underestimate conservative rasterization modes= a pixel square that is fully covered by the generating primitive must set FullyCoveredEXT to VK_TRUE if the implementation = enables the VkPhysicalDeviceConservativeRasterizationPropertiesEXT::= fullyCoveredFragmentShaderInputVariable feature.

25. Fragment Operations

Fragment operations execute on a per-fragment or per-sample basis, affec= ting whether or how a fragment or sample is written to the framebuffer. Some operations execute before fragment shading, and others after. Fragment operations always adhere to rasterization order.

25.1. Early Per-Fragment Tests

Once fragments are produced by rasterization, a number of per-fragment operations are performed prior to fragment shader execution. If a fragment is discarded during any of these operations, it will not be processed by any subsequent stage, including fragment shader execution.

The scissor test and sample mas= k generation are both always performed during early fragment tests.

Fragment operations are performed in the following order:

If early per-fragment operations are enabled= by the fragment shader, these operations are also performed:

If post-depth coverage operation is enabled by the fragment shader, the SampleMask coverage is determined after the early stencil and depth tests.

25.2. Discard Rectangles Test

The discard rectangles test determines if fragment=E2=80=99s framebuffer= coordinates (xf,yf) are inclusive or ex= clusive to a set of discard-space rectangles. The discard rectangles are set with the VkPipelineDiscardRectangleStateCreateInfoEXT pipeline state, w= hich is defined as:

typedef struct VkPipelineDiscar=
dRectangleStateCreateInfoEXT {
    VkStructureType                                  sType;
    const void*                                      pNext;
    VkPipelineDiscardRectangleStateCreateFlagsEXT    flags;
    VkDiscardRectangleModeEXT                        discardRectangleMode;
    uint32_t                                         discardRectangleCount;
    const VkRect2D*                       =
           pDiscardRectangles;
} VkPipelineDiscardRectangleStateCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • discardRectangleMode is the mode used to determine whether fragments that lie within the discard rectangle are discarded or not.

  • discardRectangleCount is the number of discard rectangles u= sed by the pipeline.

  • pDiscardRectangles is a pointer to an array of Vk= Rect2D structures, defining the discard rectangles. If the discard rectangle state is dynamic, this member is ignored.

Valid Usage
  • discardRectangleCount must b= e between 0 and VkPhysicalDeviceDiscardRectanglePropertiesEXT::maxDiscar= dRectangles, inclusive

Valid Usage (Implicit)
  • = sType must be VK_= STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT

  • flags must be 0

  • discardRectangleMode must be a valid VkDiscardRectan= gleModeEXT value

typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT;=

VkPipelineDiscardRectangleStateCreateFlagsEXT is a bitmask = type for setting a mask, but is currently reserved for future use.

The VkPipelineDiscardRectangleStateCreateInfoEXT state is s= et by adding an instance of this structure to the pNext chain of an = instance of the VkGraphicsPipelineCreateInfo structure and setting the = graphics pipeline state with vkCreateGraphicsPipelines.

If the bound pipeline state object was not created with the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT dynamic state enabled, = discard rectangles are specified using the pDiscardRectangles member o= f VkPipelineDiscardRectangleStateCreateInfoEXT linked to the pip= eline state object.

If the pipeline state object was created with the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT dynamic state enabled, = the discard rectangles are dynamically set and changed with the command:

void vkCmdSetDiscardRectangleEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstDiscardRectangle,
    uint32_t                                    discardRectangleCount,
    const VkRect2D*                       =
      pDiscardRectangles);

The discard rectangle taken from element i of = pDiscardRectangles replace the current state for the discard rectangle index firstDiscardRectangle + i, for i in [0, discardRectangleCount).

Valid Usage
Valid Usage (Implicit)
  • = commandBuffer must be a vali= d VkCommandBuffer handle

  • = pDiscardRectangles must= be a valid pointer to an array of discardRectangleCount VkRect2D structures

  • = commandBuffer must be in the= recording state

  • Th= e VkCommandPool that commandBuffer was allocated = from must support graphics operations

  • discardRectangleCount must<= /strong> be greater than 0

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

The VkOffset2D::x and VkOffset2D:= :y values of the discard rectangle VkRect2D specify the upper-left origin of th= e discard rectangle box. The lower-right corner of the discard rectangle box is specified as the VkExtent2D::width and VkExtent2D::height from the upper-left origin.

If offset.x =E2=89=A4 xf <= offset.x +=20 extent.width and offset.y =E2=89=A4 yf < offset.y + extent.height for the selected discard rectangle, th= en the fragment is within the discard rectangle box. When the discard rectangle mode is VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT a fragment within at l= east one of the active discard rectangle boxes passes the discard rectangle test; otherwise the fragment fails the discard rectangle test and is discarded. When the discard rectangle mode is VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT a fragment within at l= east one of the active discard rectangle boxes fails the discard rectangle test, and the fragment is discarded; otherwise the fragment passes the discard rectangles test. The discard rectangles test only applies to drawing commands, not to other commands like clears or copies.

Possible values of VkPipelineDiscardRectangleSta= teCreateInfoEXT::discardRectangleMode, specifying the behavior of the discard rectangle test, are:

typedef enum VkDiscardRectangle=
ModeEXT {
    VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT =3D 0,
    VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT =3D 1,
} VkDiscardRectangleModeEXT;
  • VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT specifies that a fr= agment within any discard rectangle satisfies the test.

  • VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT specifies that a fr= agment not within any of the discard rectangles satisfies the test.

25.3. Scissor Test

The scissor test determines if a fragment=E2=80=99s framebuffer coordina= tes (xf,yf) lie within the scis= sor rectangle corresponding to the viewport index (see Controlling the Viewport) used by the primitive that generated the fragment. If the pipeline state object is created without VK_DYNAMIC_STATE_SCISSOR enabled then the scissor rectangles a= re set by the VkPipelineViewportStateCreateInfo= state of the pipeline state object. Otherwise, to dynamically set the scissor rectangles call:

void vkCmdSetScissor(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstScissor,
    uint32_t                                    scissorCount,
    const VkRect2D*                       =
      pScissors);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • firstScissor is the index of the first scissor whose state = is updated by the command.

  • scissorCount is the number of scissors whose rectangles are updated by the command.

  • pScissors is a pointer to an array of VkRect2D structures defining scissor rectangles.

The scissor rectangles taken from element i of= pScissors replace the current state for the scissor index firstSciss= or + i, for i in [0, scissorCoun= t).

Each scissor rectangle is described by a VkRect2D structur= e, with the offset.x and offset.y values determining the uppe= r left corner of the scissor rectangle, and the extent.width and exten= t.height values determining the size in pixels.

Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_SCISSOR dynamic state enabled

  • firstScissor must be less th= an VkPhysicalDeviceLimits::maxViewports

  • The sum of firstScissor and scissorCount must be between 1 and VkPhysicalDeviceLimits::maxViewports<= /code>, inclusive

  • If the multiple viewports feature is not enabled, firstScissor must be 0

  • If the multiple viewports feature is not enabled, scissorCount must be 1

  • The x and y members of offset must be greater than or equal to 0

  • Evaluation of (offset.x + extent.wid= th) must not cause a signed integer addition overflow

  • Evaluation of (offset.y + extent.hei= ght) must not cause a signed integer addition overflow

Valid Usage (Implicit)
  • comman= dBuffer must be a valid VkCo= mmandBuffer handle

  • pScissors<= /code> must be a valid pointer to an arra= y of scissorCount VkRect2D structures

  • comman= dBuffer must be in the recording state

  • The VkCo= mmandPool that commandBuffer was allocated from must support graphics operations

  • sciss= orCount must be greater than 0

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

If offset.x =E2=89=A4 xf <= offset.x +=20 extent.width and offset.y =E2=89=A4 yf < offset.y + extent.height for the selected scissor rectangle, th= en the scissor test passes. Otherwise, the test fails and the fragment is discarded. For points, lines, and polygons, the scissor rectangle for a primitive is selected in the same manner as the viewport (see Controlling the Viewport). The scissor rectangles test only applies to drawing commands, not to other commands like clears or copies.

It is legal for offset.x + extent= .width or offset.y + extent.height to exceed the dimensions of the framebuffer - the scissor test still applies as defined above. Rasterization does not produce fragments outside of the framebuffer, so suc= h fragments never have the scissor test performed on them.

The scissor test is always performed. Applications can effectively disable the = scissor test by specifying a scissor rectangle that encompasses the entire framebuffer.

25.4. Sample Mask

This step modifies fragment coverage values based on the values in the pSampleMask array member of VkPipelineMultisampleStateCreateInfo<= /a>, as described previously in section Graphics Pipelines.

pSampleMask contains an array of static coverage informatio= n that is ANDed with the coverage information generated during rasteriza= tion. Bits that are zero disable coverage for the corresponding sample. Bit B of mask word M co= rresponds to sample 32 =C3=97 M + B. The array is sized to a length of =E2=8C=88 raster= izationSamples / 32 =E2=8C=89 words. If pSampleMask is NULL, it is treated as if the m= ask has all bits enabled, i.e. no coverage is removed from fragments.

The elements of the sample mask array are of type VkSampleMask, each representing 32 bits of coverage information:

typedef uint32_t VkSampleMask;

25.5. Early Fragment Test Mode

The depth bounds test, stencil test, depth test, and occlusion query sam= ple counting are performed before fragment shading if and only if early fragmen= t tests are enabled by the fragment shader (see Early Fragment Tests). When early per-fragment operations are enabled, these operations are performed prior to fragment shader execution, and the stencil buffer, depth buffer, and occlusion query sample counts will be updated accordingly; thes= e operations will not be performed again after fragment shader execution.

If a pipeline=E2=80=99s fragment shader has early fragment tests disable= d, these operations are performed only after fragment program execution, in the orde= r described below. If a pipeline does not contain a fragment shader, these operations are performed only once.

If early fragment tests are enabled, any depth value computed by the fragment shader has no effect. Additionally, the depth test (including depth writes), stencil test (including stencil writes) and sample counting operations are performed eve= n for fragments or samples that would be discarded after fragment shader execution due to per-fragment operations such as alpha-to-coverage tests, o= r due to the fragment being discarded by the shader itself.

25.6. Late Per-Fragment Tests

After programmable fragment processing, per-fragment operations are performed before blending and color output to the framebuffer.

A fragment is produced by rasterization with framebuffer coordinates of (xf,yf) and depth z, as described in Rasterization. The fragment is then modified by programmable fragment processing, which adds associated data as described in Shaders. The fragment is then further modified, and possibly discarded by the late per-fragment operations described in this chapter. Finally, if the fragment was not discarded, it is used to update the framebuffer at the fragment=E2=80=99s framebuffer coordinates for any sampl= es that remain covered.

The depth bounds test, stencil test, and depth test are performed for ea= ch pixel sample, rather than just once for each fragment. Stencil and depth operations are performed for a pixel sample only if that sample=E2=80=99s fragment coverage bit is a value of 1 when the fragment ex= ecutes the corresponding stage of the graphics pipeline. If the corresponding coverage bit is 0, no operations are performed for tha= t sample. Failure of the depth bounds, stencil, or depth test results in termination of the processing of that sample by means of disabling coverage for that sample, rather than discarding of the fragment. If, at any point, a fragment=E2=80=99s coverage becomes zero for all sample= s, then the fragment is discarded. All operations are performed on the depth and stencil values stored in the depth/stencil attachment of the framebuffer. The contents of the color attachments are not modified at this point.

The depth bounds test, stencil test, depth test, and occlusion query operations described in Depth Bounds Test, Stencil Test, Depth Test, Sample Counting are instead performed prior to fragment processing, as described in Early Fragment Test Mode, if requested by the fragment shader.

25.7. Mixed attachment samples<= /h3>

Special rules apply to per-fragment operations when the number of sample= s of the color attachments differs from the number of samples of the depth/stencil attachment used in a subpass.

Let C be the number of color attachment sample= s and D be the number of depth/stencil attachment samples used by a given subpass.

If C < D then only the first C number of samples are guaranteed to have a corresponding fragment shader invocation and thus a corresponding color output value, unless the fragment shaders produce inputs to the late per-fragment tests (e.g. by outputting to a variable decorated with the FragDepth built-in decoration). Implementations are allowed to produce fragment shader invocations for samples with indices greater than or equal to C b= ut (other than potential side effects) the color outputs of fragment shader invocations corresponding to such samples are discarded.

25.8. Multisample Coverage

If a fragment shader is active and its entry point=E2=80=99s interface i= ncludes a built-in output variable decorated with SampleMask and also de= corated with OverrideCoverageNV the fragment coverage is replaced with= the sample mask bits set in the shader. Otherwise if the built-in output variable decorated with SampleMask is not also decorated with OverrideCoverageNV then the fragment c= overage is ANDed with the bits of the sample mask to generate a new fr= agment coverage value. If such a fragment shader did not assign a value to SampleMask= due to flow of control, the value ANDed with the fragment coverage is undefined. If no fragment shader is active, or if the active fragment shader does not include SampleMask in its interface, the fragment coverage is = not modified.

Next, the fragment alpha and coverage values are modified based on the alphaToCoverageEnable and alphaToOneEnable member= s of the VkPipelineMultisampleStateCreateInfo<= /a> structure.

If alphaToCoverageEnable is enabled, a temporary coverage v= alue with rasterizationSamples bits is generated where each bit is deter= mined by the fragment=E2=80=99s alpha value. The temporary coverage value is then ANDed with the fragment coverage value to generate a new fragment coverage value.

No specific algorithm is specified for converting the alpha value to a temporary coverage mask. It is intended that the number of 1=E2=80=99s in this value be proportional= to the alpha value (clamped to [0,1]), with all 1=E2=80= =99s corresponding to a value of 1.0 and all 0=E2=80=99s corresponding to 0.0. The algorithm may be different at differe= nt pixel locations.

Note

Using different algorithms at different pixel location may help to avoid artifacts caused by regular coverage sample locations.

Next, if alphaToOneEnable is enabled, each alpha value is r= eplaced by the maximum representable alpha value for fixed-point color buffers, or by 1.0 for floating-point buffers. Otherwise, the alpha values are not changed.

25.9. Depth and Stencil Operations

Pipeline state controlling the depth bounds tests, stencil test, and depth test is specified through the members of the VkPipelineDepthStencilStateCreateInfo structure.

The VkPipelineDepthStencilStateCreateInfo structure is defi= ned as:

typedef struct VkPipelineDepthS=
tencilStateCreateInfo {
    VkStructureType                           sType;
    const void*                               pNext;
    VkPipelineDepthStencilStateCreateFlags    flags;
    VkBool32                                  depthTestEnable;
    VkBool32                                  depthWriteEnable;
    VkCompareOp                               depthCompareOp;
    VkBool32                                  depthBoundsTestEnable;
    VkBool32                                  stencilTestEnable;
    VkStencilOpState                          front;
    VkStencilOpState                          back;
    float                           =
          minDepthBounds;
    float                           =
          maxDepthBounds;
} VkPipelineDepthStencilStateCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • depthTestEnable controls whether depth testi= ng is enabled.

  • depthWriteEnable controls whether dept= h writes are enabled when depthTestEnable is VK_TRUE. Depth writes are always disabled when depthTestEnable is VK_FALSE.

  • depthCompareOp is the comparison operator used in the depth test.

  • depthBoundsTestEnable controls whether depth b= ounds testing is enabled.

  • stencilTestEnable controls whether stencil testing is enabled.

  • front and back control the parameters of the stencil test.

  • minDepthBounds and maxDepthBounds define the r= ange of values used in the depth bounds test.

Valid Usage
Valid Usage (Implicit)
typedef VkFlags VkPipelineDepthStencilStateCreateFlags;=

VkPipelineDepthStencilStateCreateFlags is a bitmask type fo= r setting a mask, but is currently reserved for future use.

25.10. Depth Bounds Test

The depth bounds test conditionally disables coverage of a sample based = on the outcome of a comparison between the value za in the depth attachment at location (xf,yf) (for the appropriate sample) and a range of values. The test is enabled or disabled by the depthBoundsTestEnable m= ember of VkPipelineDepthStencilStateCreateInf= o: If the pipeline state object is created without the VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic stat= e enabled then the range of values used in the depth bounds test are defined by the minDepthBounds and maxDepthBounds members = of the VkPipelineDepthStencilStateCreateInf= o structure. Otherwise, to dynamically set the depth bounds range values call:

void vkCmdSetDepthBounds(
    VkCommandBuffer                             commandBuffer,
    float                           =
            minDepthBounds,
    float                           =
            maxDepthBounds);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • minDepthBounds is the lower bound of the range of depth val= ues used in the depth bounds test.

  • maxDepthBounds is the upper bound of the range.

Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state enabled

  • Unless the VK_EXT_depth_range_unrest= ricted extension is enabled minDepthBounds must be betwe= en 0.0 and 1.0, inclusive

  • Unless the VK_EXT_depth_range_unrest= ricted extension is enabled maxDepthBounds must be betwe= en 0.0 and 1.0, inclusive

Valid Usage (Implicit)
  • co= mmandBuffer must be a valid = VkCommandBuffer handle

  • co= mmandBuffer must be in the recording state

  • The = VkCommandPool that commandBuffer was allocated from must support graphics operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

If minDepthBounds =E2=89=A4 za =E2=89=A4 maxDepthBounds}, then the depth bounds test passes. Otherwise, the test fails and the sample=E2=80=99s coverage bit is cleared = in the fragment. If there is no depth framebuffer attachment or if the depth bounds test is disabled, it is as if the depth bounds test always passes.

25.11. Stencil Test

The stencil test conditionally disables coverage of a sample based on th= e outcome of a comparison between the stencil value in the depth/stencil attachment at location (xf,yf) (for the appropriate sample) and a reference value. The stencil test also updates the value in the stencil attachment, dependin= g on the test state, the stencil value and the stencil write masks. The test is enabled or disabled by the stencilTestEnable membe= r of VkPipelineDepthStencilStateCreateInf= o.

When disabled, the stencil test and associated modifications are not mad= e, and the sample=E2=80=99s coverage is not modified.

The stencil test is controlled with the front and bac= k members of VkPipelineDepthStencilStateCreateInfo which are of type VkStencilOpState.

The VkStencilOpState structure is defined as:

typedef struct VkStencilOpState=
 {
    VkStencilOp    failOp;
    VkStencilOp    passOp;
    VkStencilOp    depthFailOp;
    VkCompareOp    compareOp;
    uint32_t       compareMask;
    uint32_t       writeMask;
    uint32_t       reference;
} VkStencilOpState;
  • failOp is a VkStencilOp value specifying t= he action performed on samples that fail the stencil test.

  • passOp is a VkStencilOp value specifying t= he action performed on samples that pass both the depth and stencil tests.

  • depthFailOp is a VkStencilOp value specify= ing the action performed on samples that pass the stencil test and fail the depth test.

  • compareOp is a VkCompareOp value specifyin= g the comparison operator used in the stencil test.

  • compareMask selects the bits of the unsigned integer stenci= l values participating in the stencil test.

  • writeMask selects the bits of the unsigned integer stencil = values updated by the stencil test in the stencil framebuffer attachment.

  • reference is an integer reference value that is used in the unsigned stencil comparison.

Valid Usage (Implicit)

There are two sets of stencil-related state, the front stencil state set= and the back stencil state set. Stencil tests and writes use the front set of stencil state when processing front-facing fragments and use the back set of stencil state when processin= g back-facing fragments. Fragments rasterized from non-polygon primitives (points and lines) are always considered front-facing. Fragments rasterized from polygon primitives inherit their facingness from the polygon, even if the polygon is rasterized as points or lines due to th= e current VkPolygonMode. Whether a polygon is front- or back-facing is determined in the same manner used for face culling (see Basic Polygon Rasterization).

The operation of the stencil test is also affected by the compareM= ask, writeMask, and reference members of VkStenc= ilOpState set in the pipeline state object if the pipeline state object is created withou= t the VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, and VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic states enabled, respectively.

If the pipeline state object is created with the VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled, t= hen to dynamically set the stencil compare mask call:

void vkCmdSetStencilCompareMask(
    VkCommandBuffer                             commandBuffer,
    VkStencilFaceFlags                          faceMask,
    uint32_t                                    compareMask);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • faceMask is a bitmask of VkStencilFa= ceFlagBits specifying the set of stencil state for which to update the compare mask.

  • compareMask is the new value to use as the stencil compare = mask.

Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled

Valid Usage (Implicit)
  • <= code>commandBuffer must be a valid= VkCommandBuffer handle

  • = faceMask must be a valid combinati= on of VkStencilFaceFlagBits values

  • = faceMask must not be 0=

  • <= code>commandBuffer must be in the = recording state

  • The= VkCommandPool that commandBuffer was allocated f= rom must support graphics operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

Bits which can be set in the vkCmdSetStencilCompareMask::faceMask<= /code> parameter, and similar parameters of other commands specifying which stencil state to update stencil masks for, are:

typedef enum VkStencilFaceFlagB=
its {
    VK_STENCIL_FACE_FRONT_BIT =3D 0x00000001,
    VK_STENCIL_FACE_BACK_BIT =3D 0x00000002,
    VK_STENCIL_FRONT_AND_BACK =3D 0x00000003,
} VkStencilFaceFlagBits;
  • VK_STENCIL_FACE_FRONT_BIT specifies that only the front set= of stencil state is updated.

  • VK_STENCIL_FACE_BACK_BIT specifies that only the back set o= f stencil state is updated.

  • VK_STENCIL_FRONT_AND_BACK is the combination of VK_STENCIL_FACE_FRONT_BIT and VK_STENCIL_FACE_BACK_BIT, and specifies that both sets of stencil state are updated.

typedef VkFlags VkStencilFaceFlags;

VkStencilFaceFlags is a bitmask type for setting a mask of = zero or more VkStencilFaceFlagBits.

If the pipeline state object is created with the VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled, the= n to dynamically set the stencil write mask call:

void vkCmdSetStencilWriteMask(
    VkCommandBuffer                             commandBuffer,
    VkStencilFaceFlags                          faceMask,
    uint32_t                                    writeMask);
Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled

Valid Usage (Implicit)
  • commandBuffer must be a valid <= code>VkCommandBuffer handle

  • fa= ceMask must be a valid combination= of VkStencilFaceFlagBits values

  • faceMask must not be 0

  • commandBuffer must be in the recording state

  • The <= code>VkCommandPool that commandBuffer was allocated fro= m must support graphics operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

If the pipeline state object is created with the VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled, then= to dynamically set the stencil reference value call:

void vkCmdSetStencilReference(
    VkCommandBuffer                             commandBuffer,
    VkStencilFaceFlags                          faceMask,
    uint32_t                                    reference);
Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled

Valid Usage (Implicit)
  • commandBuffer must be a valid <= code>VkCommandBuffer handle

  • fa= ceMask must be a valid combination= of VkStencilFaceFlagBits values

  • faceMask must not be 0

  • commandBuffer must be in the recording state

  • The <= code>VkCommandPool that commandBuffer was allocated fro= m must support graphics operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

reference is an integer reference value that is used in the= unsigned stencil comparison. The reference value used by stencil comparison must be within the range [0,2s-1] , where s<= /span> is the number of bits in the stencil framebuffer attachment, otherwise the reference value is considered undefined. The s least significant bits of compareMask= are bitwise ANDed with both the reference and the stored stencil value, an= d the resulting masked values are those that participate in the comparison controlled by compareOp. Let R be the masked reference value and S be the masked stored stencil value.

Possible values of VkStencilOpState::compare= Op, specifying the stencil comparison function, are:

typedef enum VkCompareOp {
    VK_COMPARE_OP_NEVER =3D 0,
    VK_COMPARE_OP_LESS =3D 1,
    VK_COMPARE_OP_EQUAL =3D 2,
    VK_COMPARE_OP_LESS_OR_EQUAL =3D 3,
    VK_COMPARE_OP_GREATER =3D 4,
    VK_COMPARE_OP_NOT_EQUAL =3D 5,
    VK_COMPARE_OP_GREATER_OR_EQUAL =3D 6,
    VK_COMPARE_OP_ALWAYS =3D 7,
} VkCompareOp;
  • VK_COMPARE_OP_NEVER specifies that the test never passes.

  • VK_COMPARE_OP_LESS specifies that the test passes when R < S.

  • VK_COMPARE_OP_EQUAL specifies that the test passes when R =3D S.

  • VK_COMPARE_OP_LESS_OR_EQUAL specifies that the test passes = when R =E2=89=A4 S.

  • VK_COMPARE_OP_GREATER specifies that the test passes when <= span class=3D"eq">R > S.

  • VK_COMPARE_OP_NOT_EQUAL specifies that the test passes when= R =E2=89=A0 S.

  • VK_COMPARE_OP_GREATER_OR_EQUAL specifies that the test pass= es when R =E2=89=A5 S.

  • VK_COMPARE_OP_ALWAYS specifies that the test always passes.=

Possible values of the failOp, passOp, and depthFailOp members of VkStencilOpState, specifying what happens = to the stored stencil value if this or certain subsequent tests fail or pass, are:

typedef enum VkStencilOp {
    VK_STENCIL_OP_KEEP =3D 0,
    VK_STENCIL_OP_ZERO =3D 1,
    VK_STENCIL_OP_REPLACE =3D 2,
    VK_STENCIL_OP_INCREMENT_AND_CLAMP =3D 3,
    VK_STENCIL_OP_DECREMENT_AND_CLAMP =3D 4,
    VK_STENCIL_OP_INVERT =3D 5,
    VK_STENCIL_OP_INCREMENT_AND_WRAP =3D 6,
    VK_STENCIL_OP_DECREMENT_AND_WRAP =3D 7,
} VkStencilOp;
  • VK_STENCIL_OP_KEEP keeps the current value.

  • VK_STENCIL_OP_ZERO sets the value to 0.

  • VK_STENCIL_OP_REPLACE sets the value to reference.

  • VK_STENCIL_OP_INCREMENT_AND_CLAMP increments the current va= lue and clamps to the maximum representable unsigned value.

  • VK_STENCIL_OP_DECREMENT_AND_CLAMP decrements the current va= lue and clamps to 0.

  • VK_STENCIL_OP_INVERT bitwise-inverts the current value.

  • VK_STENCIL_OP_INCREMENT_AND_WRAP increments the current val= ue and wraps to 0 when the maximum value would have been exceeded.

  • VK_STENCIL_OP_DECREMENT_AND_WRAP decrements the current val= ue and wraps to the maximum possible value when the value would go below 0.

For purposes of increment and decrement, the stencil bits are considered= as an unsigned integer.

If the stencil test fails, the sample=E2=80=99s coverage bit is cleared = in the fragment. If there is no stencil framebuffer attachment, stencil modification cannot occur, and it is as if the stencil tests always pass.

If the stencil test passes, the writeMask member of the VkStencilOpState structures controls how the updated = stencil value is written to the stencil framebuffer attachment.

The least significant s bits of writeMas= k, where s is the number of bits in the stencil framebuffer attachment, specify an integer mask. Where a 1 appears in this mask, the corresponding= bit in the stencil value in the depth/stencil attachment is written; where a 0 appears, the bit is not written. The writeMask value uses either the front-facing or back-facin= g state based on the facingness of the fragment. Fragments generated by front-facing primitives use the front mask and fragments generated by back-facing primitives use the back mask.

25.12. Depth Test

The depth test conditionally disables coverage of a sample based on the outcome of a comparison between the fragment=E2=80=99s depth value at the s= ample location and the sample=E2=80=99s depth value in the depth/stencil attachme= nt at location (xf,yf). The comparison is enabled or disabled with the depthTestEnable= member of the VkPipelineDepthStencilStateCr= eateInfo structure. When disabled, the depth comparison and subsequent possible updates to the value of the depth component of the depth/stencil attachment are bypassed and the fragment is passed to the next operation. The stencil value, however, can be modifi= ed as indicated above as if the depth test passed. If enabled, the comparison takes place and the depth/stencil attachment value can subsequently be modified.

The comparison is specified with the depthCompareOp member = of VkPipelineDepthStencilStateCreateInf= o. Let zf be the incoming fr= agment=E2=80=99s depth value for a sample, and let za be the depth/stencil attach= ment value in memory for that sample. The depth test passes under the following conditions:

  • VK_COMPARE_OP_NEVER: the test never passes.

  • VK_COMPARE_OP_LESS: the test passes when zf < za.

  • VK_COMPARE_OP_EQUAL: the test passes when zf =3D za.

  • VK_COMPARE_OP_LESS_OR_EQUAL: the test passes when zf =E2=89=A4 za.

  • VK_COMPARE_OP_GREATER: the test passes when zf > za.

  • VK_COMPARE_OP_NOT_EQUAL: the test passes when zf =E2=89=A0 za.

  • VK_COMPARE_OP_GREATER_OR_EQUAL: the test passes when zf =E2=89=A5 za.

  • VK_COMPARE_OP_ALWAYS: the test always passes.

If VkPipelineRasterizationStateC= reateInfo::depthClampEnable is enabled, before the incoming fragment=E2=80=99s z<= /code>f is compared to za, zf is clamped to [min(n,f),= max(n,f)], where n and f are the <= code>minDepth and maxDepth depth range values of the viewport used by this fragment, respectively.

If the depth test fails, the sample=E2=80=99s coverage bit is cleared in= the fragment. The stencil value at the sample=E2=80=99s location is updated according to = the function currently in effect for depth test failure.

If the depth test passes, the sample=E2=80=99s (possibly clamped) zf value is conditionally written to the depth framebuffer attachment based on the depthWriteEnable member of VkPipelineDepthStencilStateCreateInf= o. If depthWriteEnable is VK_TRUE the value is writt= en, and if it is VK_FALSE the value is not written. If the depth framebuffer attachment is a fixed-point format and the depth value is outside of the 0.0 to 1.0 range the dept= h value is clamped between 0.0 and 1.0 inclusive before writing. The stencil value at the sample=E2=80=99s location is updated according to = the function currently in effect for depth test success.

If there is no depth framebuffer attachment, it is as if the depth test always passes.

25.13. Sample Counting

Occlusion queries use query pool entries to track the number of samples = that pass all the per-fragment tests. The mechanism of collecting an occlusion query value is described in Occlusion Queries.

The occlusion query sample counter increments by one for each sample wit= h a coverage value of 1 in each fragment that survives all the per-fragment tests, including scissor, sample mask, alpha to coverage, stencil, and dept= h tests.

25.14. Fragment Coverage To Color

If the pNext chain of VkPipelineMultisampleStateCreateInfo includes a VkPipelineCoverageToColorStateCreateInfoNV structur= e, then that structure controls whether the fragment coverage is substituted for a fragment color output and, if so, which output is replaced.

The VkPipelineCoverageToColorStateCreateInfoNV structure is= defined as:

typedef struct VkPipelineCovera=
geToColorStateCreateInfoNV {
    VkStructureType                                sType;
    const void*                                    pNext;
    VkPipelineCoverageToColorStateCreateFlagsNV    flags;
    VkBool32                                       coverageToColorEnable;
    uint32_t                                       coverageToColorLocation;
} VkPipelineCoverageToColorStateCreateInfoNV;
  • sType is the type of this structure

  • pNext is NULL or a pointer to an extension-spe= cific structure

  • flags is reserved for future use.

  • coverageToColorEnable controls whether the fragment coverag= e value replaces a fragment color output.

  • coverageToColorLocation controls which fragment shader colo= r output value is replaced.

If coverageToColorEnable is VK_TRUE, the fragm= ent coverage information is treated as a bitmask with one bit for each sample (as in the Sample Mask section), and this bitmask replaces the first component of the color value corresponding to the fragment shader output location with Location equal to coverageToColorLo= cation and Index equal to zero. If the color attachment format has fewer bits than the sample coverage, the low bits of the sample coverage bitmask are taken without any clamping. If the color attachment format has more bits than the sample coverage, the high bits of the sample coverage bitmask are filled with zeros.

If Sample Shading is in use, the coverage bitmask only has bits set for samples that correspond to the fragment shade= r invocation that shades those samples.

This pipeline stage occurs after sample counting and before blending, an= d is always performed after fragment shading regardless of the setting of EarlyFragmentTests.

If coverageToColorEnable is VK_FALSE, these op= erations are skipped. If this structure is not present, it is as if coverageToColorEnable is VK_FALSE.

Valid Usage
  • If coverageToColorEnable is VK_TRUE, then the ren= der pass subpass indicated by VkGraphicsPipelineCreateInfo::rende= rPass and VkGraphicsPipelineCreateInfo::subpa= ss must have a color attachment at the location selected by coverageToColorLocation= , with a VkFormat of VK_FORMAT_R8_UINT, VK_FORMAT_R8_SINT, VK_FORMAT_R16_UINT, VK_FORMAT_R16_SINT, VK_FORMAT_R32_UINT, or VK_FORMAT_R32_SINT

typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV;

VkPipelineCoverageToColorStateCreateFlagsNV is a bitmask ty= pe for setting a mask, but is currently reserved for future use.

25.15. Coverage Reduction

Coverage reduction generates a color sample mask from the cover= age mask, with one bit for each sample in the color attachment(s) for the subpass. If a bit in the color sample mask is 0, then blending and writing to the framebuffer are not performed for that sample.

If the pipeline=E2=80=99s VkPipelineMultisampleStateCreateInfo<= /a>::rasterizationSamples is greater than the VkAttachmentDescription::samples of the color attachments in the subpass, then the fragment=E2=80=99s coverage is reduced= from rasterizationSamples bits to a color sample mask with VkAttachmentDescription::samples = bits. There is an implementation-dependent association of raster samples to color samples. The reduced color sample mask is computed such that the bit for each color sample is 1 if any of the associated bits in the fragment=E2=80=99s coverag= e is on, and 0 otherwise.

25.15.1. Coverage Modulation

As part of coverage reduction, fragment color values can also be modulated (multiplied) by a value that is a function of fraction of covered rasterization samples associated with that color sample.

Pipeline state controlling coverage reduction is specified through the members of the VkPipelineCoverageModulationStateCreateInfoNV structure.

The VkPipelineCoverageModulationStateCreateInfoNV structure= is defined as:

typedef struct VkPipelineCovera=
geModulationStateCreateInfoNV {
    VkStructureType                                   sType;
    const void*                                       pNext;
    VkPipelineCoverageModulationStateCreateFlagsNV    flags;
    VkCoverageModulationModeNV                        coverageModulationMod=
e;
    VkBool32                                          coverageModulationTab=
leEnable;
    uint32_t                                          coverageModulationTab=
leCount;
    const =
float*                                      pCoverageModulationTable=
;
} VkPipelineCoverageModulationStateCreateInfoNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • coverageModulationMode controls which color components are modulated and is of type VkCoverageModulationMo= deNV.

  • coverageModulationTableEnable controls whether the modulati= on factor is looked up from a table in pCoverageModulationTable.<= /p>

  • coverageModulationTableCount is the number of elements in pCoverageModulationTable.

  • pCoverageModulationTable is a table of modulation factors containing a value for each number of covered samples.

If coverageModulationTableEnable is VK_FALSE, = then for each color sample the associated bits of the fragment=E2=80=99s coverage are cou= nted and divided by the number of associated bits to produce a modulation factor R in the range (0,1] (a= value of zero would have been killed due to a color coverage of 0). Specifically:

  • N =3D value of rasterizationSamples

  • M =3D value of VkAtta= chmentDescription::samples for any color attachments

  • R =3D popcount(associated coverage bits) / (N / M)

If coverageModulationTableEnable is VK_TRUE, t= he value R is computed using a programmable lookup table. The lookup table has N / M elements, and the elem= ent of the table is selected by:

  • R =3D pCoverageModulationTable[popcount(= associated coverage bits)-1]

Note that the table does not have an entry for popcou= nt(associated coverage bits) =3D 0, because such samples would have been killed.

The values of pCoverageModulationTable may be rounded to an implementation-dependent precision, which is at least as fine as 1 / N, and clamped to [0,1].

For each color attachment with a floating point or normalized color form= at, each fragment output color value is replicated to M values which can each be modulated (multiplied) by that color sample=E2=80=99s associated va= lue of R. Which components are modulated is controlled by coverageModulationMode.

If this structure is not present, it is as if coverageModulationMode is VK_COVERAGE_MODULATION_MODE_NONE_NV.

Valid Usage
  • If coverageModulationTableEnable is VK_TRUE, coverageModulationTableCount must be equal to the number of rasterization samples divided by the number of color samples in the subpass.

Valid Usage (Implicit)
  • sType must be VK= _STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV

  • flags must be 0

  • coverageModulationMode must be a valid VkCoverag= eModulationModeNV value

  • coverageModulationTableCount must be greater than 0

typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV=
;

VkPipelineCoverageModulationStateCreateFlagsNV is a bitmask= type for setting a mask, but is currently reserved for future use.

Possible values of VkPipelineCoverageModulation= StateCreateInfoNV::coverageModulationMode, specifying which color components are modulated, are:

typedef enum VkCoverageModulati=
onModeNV {
    VK_COVERAGE_MODULATION_MODE_NONE_NV =3D 0,
    VK_COVERAGE_MODULATION_MODE_RGB_NV =3D 1=
,
    VK_COVERAGE_MODULATION_MODE_ALPHA_NV =3D 2,
    VK_COVERAGE_MODULATION_MODE_RGBA_NV =3D 3,
} VkCoverageModulationModeNV;
  • VK_COVERAGE_MODULATION_MODE_NONE_NV specifies that no compo= nents are multiplied by the modulation factor.

  • VK_COVERAGE_MODULATION_MODE_RGB_NV specifies that the red, = green, and blue components are multiplied by the modulation factor.

  • VK_COVERAGE_MODULATION_MODE_ALPHA_NV specifies that the alp= ha component is multiplied by the modulation factor.

  • VK_COVERAGE_MODULATION_MODE_RGBA_NV specifies that all comp= onents are multiplied by the modulation factor.

26. The Framebuffer

26.1. Blending

Blending combines the incoming source fragment=E2=80=99s R, G, = B, and A values with the destination R, G, B, and A values of each sample stored i= n the framebuffer at the fragment=E2=80=99s (xf,yf) location. Blending is performed for each pixel sample, rather than just once for each fragment.

Source and destination values are combined according to the blend operation, quadruplets of source and destination weighting factors determined by the b= lend factors, and a blend constant, to obtain a new set of R, G, B, and A values, as described below.

Blending is computed and applied separately to each color attachment use= d by the subpass, with separate controls for each attachment.

Prior to performing the blend operation, signed and unsigned normalized fixed-point color components undergo an implied conversion to floating-poin= t as specified by Conversion from Normalized Fixed-Point to Floating-Point. Blending computations are treated as if carried out in floating-point, and basic blend operations are performed with a precision and dynamic range no lower than that used to represent destination components. Advanced blending operations are performed with a precision and dynamic range no lower than the smaller of that used t= o represent destination components or that used to represent 16-bit floating-point values.

Blending applies only to fixed-point and floating-point color attachment= s. If the color attachment has an integer format, blending is not applied.

The pipeline blend state is included in the VkPipelineColorBlendStateCreateInfo structure during graphics = pipeline creation:

The VkPipelineColorBlendStateCreateInfo structure is define= d as:

typedef struct VkPipelineColorB=
lendStateCreateInfo {
    VkStructureType                               sType;
    const void*                                   pNext;
    VkPipelineColorBlendStateCreateFlags          flags;
    VkBool32                                      logicOpEnable;
    VkLogicOp                                     logicOp;
    uint32_t                                      attachmentCount;
    const VkPipelineColorBlendAttachmentSt=
ate*    pAttachments;
    float                           =
              blendConstants[4];
} VkPipelineColorBlendStateCreateInfo;

Each element of the pAttachments array is a VkPipelineColorBlendAttachmentState structure specifying per-target blending state for each individual color attachment. If the independent blending feature is not enabled on the device, all VkPi= pelineColorBlendAttachmentState elements in the pAttachments array mu= st be identical.

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO

  • pNext must be NULL = or a pointer to a valid instance of VkPipelineColorBlendAdvancedStateCreateInfoEXT

  • flags must be 0

  • If attachmentCount is not 0, pAttach= ments must be a valid pointer to a= n array of attachmentCount valid VkPipelineColorBlendAtt= achmentState structures

typedef VkFlags VkPipelineColorBlendStateCreateFlags;

VkPipelineColorBlendStateCreateFlags is a bitmask type for = setting a mask, but is currently reserved for future use.

The VkPipelineColorBlendAttachmentState structure is define= d as:

typedef struct VkPipelineColorB=
lendAttachmentState {
    VkBool32                 blendEnable;
    VkBlendFactor            srcColorBlendFactor;
    VkBlendFactor            dstColorBlendFactor;
    VkBlendOp                colorBlendOp;
    VkBlendFactor            srcAlphaBlendFactor;
    VkBlendFactor            dstAlphaBlendFactor;
    VkBlendOp                alphaBlendOp;
    VkColorComponentFlags    colorWriteMask;
} VkPipelineColorBlendAttachmentState;
  • blendEnable controls whether blending is enabled for the corresponding color attachment. If blending is not enabled, the source fragment=E2=80=99s color for that attachment is passed through unmodified.

  • srcColorBlendFactor selects which blend factor is used to determine the source factors (Sr,Sg,Sb).

  • dstColorBlendFactor selects which blend factor is used to determine the destination factors (Dr,Dg= ,Db).

  • colorBlendOp selects which blend operation is used to calcu= late the RGB values to write to the color attachment.

  • srcAlphaBlendFactor selects which blend factor is used to determine the source factor Sa.

  • dstAlphaBlendFactor selects which blend factor is used to determine the destination factor Da.

  • alphaBlendOp selects which blend operation is use to calcul= ate the alpha values to write to the color attachment.

  • colorWriteMask is a bitmask of Vk= ColorComponentFlagBits specifying which of the R, G, B, and/or A components are enabled for writing, as described for the Color Write Mask.

Valid Usage
  • If the dual source blending feature is not enabled, srcColorBlendFactor m= ust not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

  • If the dual source blending feature is not enabled, dstColorBlendFactor m= ust not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

  • If the dual source blending feature is not enabled, srcAlphaBlendFactor m= ust not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

  • If the dual source blending feature is not enabled, dstAlphaBlendFactor m= ust not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

  • If either of colorBlendOp or alphaBlendOp is an advanced blend operation, then colorBlendOp must equal alphaBlendOp

  • If VkPhysicalDeviceBlendO= perationAdvancedPropertiesEXT::advancedBlendIndependentBlend is VK_FALSE and colorBlendOp is an advanced blend operation, then colorBlendOp must be the sam= e for all attachments.

  • If VkPhysicalDeviceBlendO= perationAdvancedPropertiesEXT::advancedBlendIndependentBlend is VK_FALSE and alphaBlendOp is an advanced blend operation, then alphaBlendOp must be the sam= e for all attachments.

  • If VkPhysicalDeviceBlendO= perationAdvancedPropertiesEXT::advancedBlendAllOperations is VK_FALSE, then colorBlendOp must not be VK_BLEND_OP_ZERO_EXT, VK_BLEND_OP_SRC_EXT, VK_BLEND_OP_DST_EXT, VK_BLEND_OP_SRC_OVER_EXT, VK_BLEND_OP_DST_OVER_EXT, VK_BLEND_OP_SRC_IN_EXT, VK_BLEND_OP_DST_IN_EXT, VK_BLEND_OP_SRC_OUT_EXT, VK_BLEND_OP_DST_OUT_EXT, VK_BLEND_OP_SRC_ATOP_EXT= , VK_BLEND_OP_DST_ATOP_EXT, VK_BLEND_OP_XOR_EXT, VK_BLEND_OP_INVERT_EXT, VK_BLEND_OP_INVERT_RGB_EXT, VK_BLEND_OP_LINEARDODGE_EXT, VK_BLEND_OP_LINEARBURN_EXT<= /code>, VK_BLEND_OP_VIVIDLIGHT_EXT, VK_BLEND_OP_LINEARLIGHT_EXT<= /code>, VK_BLEND_OP_PINLIGHT_EXT, VK_BLEND_OP_HARDMIX_EXT= , VK_BLEND_OP_PLUS_EXT, VK_BLEND_OP_PLUS_CLAMPED_EXT, VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT, VK_BLEND_OP_PLUS_DARKER_EXT, VK_BLEND_OP_MINUS_EXT, VK_BLEND_OP_MINUS_CLAMPED_EXT, VK_BLEND_OP_CONTRAST_EXT<= /code>, VK_BLEND_OP_INVERT_OVG_EXT, VK_BLEND_OP_RED_EXT, VK_BLEND_OP_GREEN_EXT, or VK_BLEND_OP_BLUE_EXT

  • If colorBlendOp or alphaBlendOp is an advanced blend operation, then VkSubpassDescription::colorAttachmentCount<= /code> of the subpass this pipeline is compiled against must be= less than or equal to VkPhysicalDeviceBlendO= perationAdvancedPropertiesEXT::advancedBlendMaxColorAttachments

Valid Usage (Implicit)

26.1.1. Blend Factors

The source and destination color and alpha blending factors are selected from the enum:

typedef enum VkBlendFactor {
    VK_BLEND_FACTOR_ZERO =3D 0,
    VK_BLEND_FACTOR_ONE =3D 1,
    VK_BLEND_FACTOR_SRC_COLOR =3D 2,
    VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR =3D 3,
    VK_BLEND_FACTOR_DST_COLOR =3D 4,
    VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR =3D 5,
    VK_BLEND_FACTOR_SRC_ALPHA =3D 6,
    VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA =3D 7,
    VK_BLEND_FACTOR_DST_ALPHA =3D 8,
    VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA =3D 9,
    VK_BLEND_FACTOR_CONSTANT_COLOR =3D 10,
    VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR =3D 11=
,
    VK_BLEND_FACTOR_CONSTANT_ALPHA =3D 12,
    VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA =3D 13=
,
    VK_BLEND_FACTOR_SRC_ALPHA_SATURATE =3D 14,
    VK_BLEND_FACTOR_SRC1_COLOR =3D 15,
    VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR =3D 16,
    VK_BLEND_FACTOR_SRC1_ALPHA =3D 17,
    VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA =3D 18,
} VkBlendFactor;

The semantics of each enum value is described in the table below:

Table 33. Blend Factors
VkBlendFacto= r RGB Blend Factors (Sr,Sg,Sb) or (Dr,Dg,Db) Alpha Blend Factor (Sa or Da= )

VK_BLEND_FACTOR_ZERO

(0,0,0)

0

VK_BLEND_FACTOR_ONE

(1,1,1)

1

VK_BLEND_FACTOR_SRC_COLOR

(Rs0,Gs0,Bs0)

As0

VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR

(1-Rs0,1-Gs0,1-Bs0)=

1-As0

VK_BLEND_FACTOR_DST_COLOR

(Rd,Gd,Bd)

Ad

VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR

(1-Rd,1-Gd,1-Bd)

1-Ad

VK_BLEND_FACTOR_SRC_ALPHA

(As0,As0,As0)

As0

VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA

(1-As0,1-As0,1-As0)=

1-As0

VK_BLEND_FACTOR_DST_ALPHA

(Ad,Ad,Ad)

Ad

VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA

(1-Ad,1-Ad,1-Ad)

1-Ad

VK_BLEND_FACTOR_CONSTANT_COLOR

(Rc,Gc,Bc)

Ac

VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR

(1-Rc,1-Gc,1-Bc)

1-Ac

VK_BLEND_FACTOR_CONSTANT_ALPHA

(Ac,Ac,Ac)

Ac

VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA

(1-Ac,1-Ac,1-Ac)

1-Ac

VK_BLEND_FACTOR_SRC_ALPHA_SATURATE

(f,f,f); f =3D min(As0= ,1-Ad)

1

VK_BLEND_FACTOR_SRC1_COLOR

(Rs1,Gs1,Bs1)

As1

VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR

(1-Rs1,1-Gs1,1-Bs1)=

1-As1

VK_BLEND_FACTOR_SRC1_ALPHA

(As1,As1,As1)

As1

VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

(1-As1,1-As1,1-As1)=

1-As1

In this table, the following conventions are used:

  • Rs0,Gs0,Bs0 a= nd As0 represent the first source colo= r R, G, B, and A components, respectively, for the fragment output location corresponding to the color attachment being blended.

  • Rs1,Gs1,Bs1 a= nd As1 represent the second source color R, G, B, and A components, respectively, used in dual source blending modes, for the fragment output location corresponding to the color attachment being blended.

  • Rd,Gd,Bd and = Ad represent the R, G, B, and A components of the destination color. That is, the color currently in the corresponding color attachment for this fragment/sample.

  • Rc,Gc,Bc and = Ac represent the blend constant R, G, B, and A components, respectively.

If the pipeline state object is created without the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled then th= e blend constant (Rc,Gc,Bc= ,Ac) is specified via the blendConstants member of = VkPipelineColorBlendStateCreateInfo.

Otherwise, to dynamically set and change the blend constant, call:

void vkCmdSetBlendConstants(
    VkCommandBuffer                             commandBuffer,
    const =
float                                 blendConstants[4]);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • blendConstants is an array of four values specifying the R,= G, B, and A components of the blend constant color used in blending, depending on the blend factor.

Valid Usage
  • The bound graphics pipeline must have bee= n created with the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from = must support graphics operations

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics

26.1.2. Dual-Source Blending

Blend factors that use the secondary color input (Rs1,Gs1,Bs1,As1) (VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, and VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA) may consume implementation resources that could otherwise be used for rendering to multiple color attachments. Therefore, the number of color attachments that ca= n be used in a framebuffer may be lower when using dual-= source blending.

Dual-source blending is only supported if the dualSrcBlend feature is en= abled.

The maximum number of color attachments that ca= n be used in a subpass when using dual-source blending functions is implementation-dependent and is reported as the maxFragmentDualSrcAttachments member of VkPhysicalDeviceLimits.

When using a fragment shader with dual-source blending functions, the co= lor outputs are bound to the first and second inputs of the blender using the Index decoration, as described in F= ragment Output Interface. If the second color input to the blender is not written in the shader, or i= f no output is bound to the second input of a blender, the result of the blending operation is not defined.

26.1.3. Blend Operations

Once the source and destination blend factors have been selected, they a= long with the source and destination components are passed to the blending operations. RGB and alpha components can use differen= t operations. Possible values of VkBlendOp, specifying the operations, are= :

typedef enum VkBlendOp {
    VK_BLEND_OP_ADD =3D 0,
    VK_BLEND_OP_SUBTRACT =3D 1,
    VK_BLEND_OP_REVERSE_SUBTRACT =3D 2,
    VK_BLEND_OP_MIN =3D 3,
    VK_BLEND_OP_MAX =3D 4,
    VK_BLEND_OP_ZERO_EXT =3D 1000148000,
    VK_BLEND_OP_SRC_EXT =3D 1000148001,
    VK_BLEND_OP_DST_EXT =3D 1000148002,
    VK_BLEND_OP_SRC_OVER_EXT =3D 1000148003,
    VK_BLEND_OP_DST_OVER_EXT =3D 1000148004,
    VK_BLEND_OP_SRC_IN_EXT =3D 1000148005,
    VK_BLEND_OP_DST_IN_EXT =3D 1000148006,
    VK_BLEND_OP_SRC_OUT_EXT =3D 1000148007,
    VK_BLEND_OP_DST_OUT_EXT =3D 1000148008,
    VK_BLEND_OP_SRC_ATOP_EXT =3D 1000148009,
    VK_BLEND_OP_DST_ATOP_EXT =3D 1000148010,
    VK_BLEND_OP_XOR_EXT =3D 1000148011,
    VK_BLEND_OP_MULTIPLY_EXT =3D 1000148012,
    VK_BLEND_OP_SCREEN_EXT =3D 1000148013,
    VK_BLEND_OP_OVERLAY_EXT =3D 1000148014,
    VK_BLEND_OP_DARKEN_EXT =3D 1000148015,
    VK_BLEND_OP_LIGHTEN_EXT =3D 1000148016,
    VK_BLEND_OP_COLORDODGE_EXT =3D 1000148017,
    VK_BLEND_OP_COLORBURN_EXT =3D 1000148018=
,
    VK_BLEND_OP_HARDLIGHT_EXT =3D 1000148019=
,
    VK_BLEND_OP_SOFTLIGHT_EXT =3D 1000148020=
,
    VK_BLEND_OP_DIFFERENCE_EXT =3D 1000148021,
    VK_BLEND_OP_EXCLUSION_EXT =3D 1000148022=
,
    VK_BLEND_OP_INVERT_EXT =3D 1000148023,
    VK_BLEND_OP_INVERT_RGB_EXT =3D 1000148024,
    VK_BLEND_OP_LINEARDODGE_EXT =3D 1000148025,
    VK_BLEND_OP_LINEARBURN_EXT =3D 1000148026,
    VK_BLEND_OP_VIVIDLIGHT_EXT =3D 1000148027,
    VK_BLEND_OP_LINEARLIGHT_EXT =3D 1000148028,
    VK_BLEND_OP_PINLIGHT_EXT =3D 1000148029,
    VK_BLEND_OP_HARDMIX_EXT =3D 1000148030,
    VK_BLEND_OP_HSL_HUE_EXT =3D 1000148031,
    VK_BLEND_OP_HSL_SATURATION_EXT =3D 1000148032,
    VK_BLEND_OP_HSL_COLOR_EXT =3D 1000148033=
,
    VK_BLEND_OP_HSL_LUMINOSITY_EXT =3D 1000148034,
    VK_BLEND_OP_PLUS_EXT =3D 1000148035,
    VK_BLEND_OP_PLUS_CLAMPED_EXT =3D 1000148036,
    VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT =3D 10001480=
37,
    VK_BLEND_OP_PLUS_DARKER_EXT =3D 1000148038,
    VK_BLEND_OP_MINUS_EXT =3D 1000148039,
    VK_BLEND_OP_MINUS_CLAMPED_EXT =3D 1000148040,
    VK_BLEND_OP_CONTRAST_EXT =3D 1000148041,
    VK_BLEND_OP_INVERT_OVG_EXT =3D 1000148042,
    VK_BLEND_OP_RED_EXT =3D 1000148043,
    VK_BLEND_OP_GREEN_EXT =3D 1000148044,
    VK_BLEND_OP_BLUE_EXT =3D 1000148045,
} VkBlendOp;

The semantics of each basic blend operations is described in the table below:

Table 34. Basic Blend Operations
VkBlendOp RGB Components Alpha Component

VK_BLEND_OP_ADD

R =3D Rs0 =C3=97 Sr + Rd = =C3=97 Dr
G =3D Gs0 =C3=97 Sg + Gd =C3=97 Dg
B =3D Bs0 =C3=97 Sb + Bd =C3=97 Db

A =3D As0 =C3=97 Sa + Ad = =C3=97 Da

VK_BLEND_OP_SUBTRACT

R =3D Rs0 =C3=97 Sr - Rd = =C3=97 Dr
G =3D Gs0 =C3=97 Sg - Gd =C3=97 Dg
B =3D Bs0 =C3=97 Sb - Bd =C3=97 Db

A =3D As0 =C3=97 Sa - Ad = =C3=97 Da

VK_BLEND_OP_REVERSE_SUBTRACT

R =3D Rd =C3=97 Dr - Rs0 = =C3=97 Sr
G =3D Gd =C3=97 Dg - Gs0 =C3=97 Sg
B =3D Bd =C3=97 Db - Bs0 =C3=97 Sb

A =3D Ad =C3=97 Da - As0 = =C3=97 Sa

VK_BLEND_OP_MIN

R =3D min(Rs0,Rd)
G =3D min(Gs0,Gd)
B =3D min(Bs0,Bd)

A =3D min(As0,Ad)

VK_BLEND_OP_MAX

R =3D max(Rs0,Rd)
G =3D max(Gs0,Gd)
B =3D max(Bs0,Bd)

A =3D max(As0,Ad)

In this table, the following conventions are used:

  • Rs0, Gs0, Bs0= and As0 represent the first source color R, G, B, and A components, respectively.

  • Rd, Gd, Bd an= d Ad represent the R, G, B, and A components of the destination color. That is, the color currently in the corresponding color attachment for this fragment/sample.

  • Sr, Sg, Sb an= d Sa represent the source blend factor R, G, B, and A components, respectively.

  • Dr, Dg, Db an= d Da represent the destination blend factor R, G, B, and A components, respectively.

The blending operation produces a new set of values R= , G, B and A, which are written to the framebuffer attachmen= t. If blending is not enabled for this attachment, then R, = G, B and A are assigned Rs0,= Gs0, Bs0 and As0, respectively.

If the color attachment is fixed-point, the components of the source and destination values and blend factors are each clamped to [0,1] or [-1,1] respectively for an unsigned normalized or= signed normalized color attachment prior to evaluating the blend operations. If the color attachment is floating-point, no clamping occurs.

If the numeric format of a framebuffer attachment uses sRGB encoding, th= e R, G, and B destination color values (after conversion from fixed-point to floating-point) are considered to be encoded for the sRGB color space and hence are linearized prior to their use in blending. Each R, G, and B component is converted from nonlinear to linear as described in the =E2=80=9CsRGB EOTF=E2=80=9D section of the Kh= ronos Data Format Specification. If the format is not sRGB, no linearization is performed.

If the numeric format of a framebuffer attachment uses sRGB encoding, th= en the final R, G and B values are converted into the nonlinear sRGB representation before being written to the framebuffer attachment as described in the =E2=80=9CsRGB EOTF -1=E2=80=9D section of = the Khronos Data Format Specification.

If the framebuffer color attachment numeric format is not sRGB encoded t= hen the resulting cs values for R, G and B= are unmodified. The value of A is never sRGB encoded. That is, the alpha component is always stored in memory as linear.

If the framebuffer color attachment is VK_ATTACHMENT_UNUSED= , no writes are performed through that attachment. Framebuffer color attachments greater than or equal to VkSubpassDescription::colorAttachmentCount perfor= m no writes.

26.1.4. Advanced Blend Operations

If the pNext chain of = VkPipelineColorBlendStateCreateInfo includes a VkPipelineColorBlendAdvancedStateCreateInfoEXT stru= cture, then that structure includes parameters that affect advanced blend operations.

The VkPipelineColorBlendAdvancedStateCreateInfoEXT structur= e is defined as:

typedef struct VkPipelineColorB=
lendAdvancedStateCreateInfoEXT {
    VkStructureType      sType;
    const void*          pNext;
    VkBool32             srcPremultiplied;
    VkBool32             dstPremultiplied;
    VkBlendOverlapEXT    blendOverlap;
} VkPipelineColorBlendAdvancedStateCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • srcPremultiplied specifies whether the source color of the = blend operation is treated as premultiplied.

  • dstPremultiplied specifies whether the destination color of= the blend operation is treated as premultiplied.

  • blendOverlap is a VkBlendOverlapEXT = value specifying how the source and destination sample=E2=80=99s coverage is correlated.

If this structure is not present, srcPremultiplied and dstPremultiplied are both considered to be VK_TRUE, and blendOverlap is considered to be VK_BLEND_OVERLAP_UNCORRELATED_EXT.

Valid Usage
Valid Usage (Implicit)
  • sType must be V= K_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT=

  • blendOverlap must be a valid VkBlendOverlapEXT value

When using one of the operations in table f/X/Y/Z Advanced Blend Operations or Hue-Saturation-Luminosity Advanced Blend Operations, blending is performed according to the following equations:

\[\begin{aligned} R & =3D & f(R_s',R_d')*p_0(A_s,A_d) & + & Y*R_s'*p_1(A_s,= A_d) & + & Z*R_d'*p_2(A_s,A_d) \\ G & =3D & f(G_s',G_d')*p_0(A_s,A_d) & + & Y*G_s'*p_1(A_s,= A_d) & + & Z*G_d'*p_2(A_s,A_d) \\ B & =3D & f(B_s',B_d')*p_0(A_s,A_d) & + & Y*B_s'*p_1(A_s,= A_d) & + & Z*B_d'*p_2(A_s,A_d) \\ A & =3D & X*p_0(A_s,A_d) & + & Y*p_1(A_s,= A_d) & + & Z*p_2(A_s,A_d) \end{aligned}\]

where the function f and terms X, Y, and Z are specified in the table. The R, G, and B components of the source color used for blending are derive= d according to srcPremultiplied. If srcPremultiplied is set to VK_TRUE, the fragme= nt color components are considered to have been premultiplied by the A component prior to blending. The base source color (Rs',Gs',Bs') is obtained by dividing through by the A component:

\[\begin{aligned} (R_s', G_s', B_s') & =3D \begin{cases} (0, 0, 0) & A_s =3D 0 \\ (\frac{R_s}{A_s}, \frac{G_s}{A_s}, \frac{B_s}{A_s}) & \text{otherw= ise} \end{cases} \end{aligned}\]

If srcPremultiplied is VK_FALSE, the fragment = color components are used as the base color:

\[\begin{aligned} (R_s', G_s', B_s') & =3D (R_s, G_s, B_s) \end{aligned}\]

The R, G, and B components of the destination color used for blending ar= e derived according to dstPremultiplied. If dstPremultiplied is set to VK_TRUE, the destin= ation components are considered to have been premultiplied by the A component prior to blending. The base destination color (Rd',Gd= ',Bd') is obtained by dividing through by the A component:

\[\begin{aligned} (R_d', G_d', B_d') & =3D \begin{cases} (0, 0, 0) & A_d =3D 0 \\ (\frac{R_d}{A_d}, \frac{G_d}{A_d}, \frac{B_d}{A_d}) & \text{otherw= ise} \end{cases} \end{aligned}\]

If dstPremultiplied is VK_FALSE, the destinati= on color components are used as the base color:

\[\begin{aligned} (R_d', G_d', B_d') & =3D (R_d, G_d, B_d) \end{aligned}\]

When blending using advanced blend operations, we expect that the R, G, = and B components of premultiplied source and destination color inputs be stored as the product of non-premultiplied R, G, and B component values and the A component of the color. If any R, G, or B component of a premultiplied input color is non-zero and the A component is zero, the color is considered ill-formed, and the corresponding component of the blend result is undefined.

The weighting functions p0, p1, and p2 are defined in table Advanced Blend Overlap Modes. In these functions, the A components of the source and destination colors are taken to indicate the portion of the pixel covered by the fragment (source) and the fragments previously accumulated in the pixel (destination). The functions p0, p= 1, and p2 approximat= e the relative portion of the pixel covered by the intersection of the source and destination, covered only by the source, and covered only by the destination, respectively.

Possible values of VkPipelineColorBlendAdvance= dStateCreateInfoEXT::blendOverlap, specifying the blend overlap functions, are:

typedef enum VkBlendOverlapEXT =
{
    VK_BLEND_OVERLAP_UNCORRELATED_EXT =3D 0,
    VK_BLEND_OVERLAP_DISJOINT_EXT =3D 1,
    VK_BLEND_OVERLAP_CONJOINT_EXT =3D 2,
} VkBlendOverlapEXT;
  • VK_BLEND_OVERLAP_UNCORRELATED_EXT specifies that there is n= o correlation between the source and destination coverage.

  • VK_BLEND_OVERLAP_CONJOINT_EXT specifies that the source and destination coverage are considered to have maximal overlap.

  • VK_BLEND_OVERLAP_DISJOINT_EXT specifies that the source and destination coverage are considered to have minimal overlap.

Table 35. Advanced Blend Overlap Modes
Overlap Mode Weighting Equations

VK_BLEND_OVERLAP_UNCORRELATED_EXT

\[ \begin{aligned} p_0(A_s,A_d) & =3D A_sA= _d \\ p_1(A_s,A_d) & =3D A_s(= 1-A_d) \\ p_2(A_s,A_d) & =3D A_d(= 1-A_s) \\ \end{aligned}\]

VK_BLEND_OVERLAP_CONJOINT_EXT

\[ \begin{aligned} p_0(A_s,A_d) & =3D min(= A_s,A_d) \\ p_1(A_s,A_d) & =3D max(= A_s-A_d,0) \\ p_2(A_s,A_d) & =3D max(= A_d-A_s,0) \\ \end{aligned}\]

VK_BLEND_OVERLAP_DISJOINT_EXT

\[ \begin{aligned} p_0(A_s,A_d) & =3D max(= A_s+A_d-1,0) \\ p_1(A_s,A_d) & =3D min(= A_s,1-A_d) \\ p_2(A_s,A_d) & =3D min(= A_d,1-A_s) \\ \end{aligned}\]
Table 36. f/X/Y/Z Advanced Blend Operations
Mode Blend Coefficients

VK_BLEND_OP_ZERO_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (0,0,0) \= \ f(C_s,C_d) & =3D 0 \end{aligned}\]

VK_BLEND_OP_SRC_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,0) \= \ f(C_s,C_d) & =3D C_s \end{aligned}\]

VK_BLEND_OP_DST_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,0,1) \= \ f(C_s,C_d) & =3D C_d \end{aligned}\]

VK_BLEND_OP_SRC_OVER_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D C_s \end{aligned}\]

VK_BLEND_OP_DST_OVER_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D C_d \end{aligned}\]

VK_BLEND_OP_SRC_IN_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,0,0) \= \ f(C_s,C_d) & =3D C_s \end{aligned}\]

VK_BLEND_OP_DST_IN_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,0,0) \= \ f(C_s,C_d) & =3D C_d \end{aligned}\]

VK_BLEND_OP_SRC_OUT_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (0,1,0) \= \ f(C_s,C_d) & =3D 0 \end{aligned}\]

VK_BLEND_OP_DST_OUT_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (0,0,1) \= \ f(C_s,C_d) & =3D 0 \end{aligned}\]

VK_BLEND_OP_SRC_ATOP_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,0,1) \= \ f(C_s,C_d) & =3D C_s \end{aligned}\]

VK_BLEND_OP_DST_ATOP_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,0) \= \ f(C_s,C_d) & =3D C_d \end{aligned}\]

VK_BLEND_OP_XOR_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (0,1,1) \= \ f(C_s,C_d) & =3D 0 \end{aligned}\]

VK_BLEND_OP_MULTIPLY_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D C_sC_d \end{aligned}\]

VK_BLEND_OP_SCREEN_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D C_s+C_= d-C_sC_d \end{aligned}\]

VK_BLEND_OP_OVERLAY_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} 2 C_sC_d &am= p; C_d \leq 0.5 \\ 1-2 (1-C_s)(1-C_d) &am= p; \text{otherwise} \end{cases} \end{aligned}\]

VK_BLEND_OP_DARKEN_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D min(C_= s,C_d) \end{aligned}\]

VK_BLEND_OP_LIGHTEN_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D max(C_= s,C_d) \end{aligned}\]

VK_BLEND_OP_COLORDODGE_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} 0 = & C_d \leq 0 \\ min(1,\frac{C_d}{1-C_s}) = & C_d \gt 0 \text{ and } C_s \lt 1 \\ 1 = & C_d \gt 0 \text{ and } C_s \geq 1 \end{cases} \end{aligned}\]

VK_BLEND_OP_COLORBURN_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} 1 = & C_d \geq 1 \\ 1 - min(1,\frac{1-C_d}{C_= s}) & C_d \lt 1 \text{ and } C_s \gt 0 \\ 0 = & C_d \lt 1 \text{ and } C_s \leq 0 \end{cases} \end{aligned}\]

VK_BLEND_OP_HARDLIGHT_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} 2 C_sC_d &am= p; C_s \leq 0.5 \\ 1-2 (1-C_s)(1-C_d) &am= p; \text{otherwise} \end{cases} \end{aligned}\]

VK_BLEND_OP_SOFTLIGHT_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} C_d-(1-2 C_s)C_d(1-C_d) = & C_s \leq 0.5 \\ C_d+(2 C_s-1)C_d((16 C_d-= 12)C_d+3) & C_s \gt 0.5 \text{ and } C_d \leq 0.25 \\ C_d+(2 C_s-1)(\sqrt{C_d}-= C_d) & C_s \gt 0.5 \text{ and } C_d \gt 0.25 \end{cases} \end{aligned}\]

VK_BLEND_OP_DIFFERENCE_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \lvert= C_d-C_s \rvert \end{aligned}\]

VK_BLEND_OP_EXCLUSION_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D C_s+C_= d-2C_sC_d \end{aligned}\]

VK_BLEND_OP_INVERT_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,0,1) \= \ f(C_s,C_d) & =3D 1-C_d \end{aligned}\]

VK_BLEND_OP_INVERT_RGB_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,0,1) \= \ f(C_s,C_d) & =3D C_s(1-= C_d) \end{aligned}\]

VK_BLEND_OP_LINEARDODGE_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} C_s+C_d & C= _s+C_d \leq 1 \\ 1 & \= text{otherwise} \end{cases} \end{aligned}\]

VK_BLEND_OP_LINEARBURN_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} C_s+C_d-1 & C= _s+C_d \gt 1 \\ 0 & \= text{otherwise} \end{cases} \end{aligned}\]

VK_BLEND_OP_VIVIDLIGHT_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} 1-min(1,\frac{1-C_d}{2C_s= }) & 0 \lt C_s \lt 0.5 \\ 0 = & C_s \leq 0 \\ min(1,\frac{C_d}{2(1-C_s)= }) & 0.5 \leq C_s \lt 1 \\ 1 = & C_s \geq 1 \end{cases} \end{aligned}\]

VK_BLEND_OP_LINEARLIGHT_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} 1 = & 2C_s+C_d \gt 2 \\ 2C_s+C_d-1 = & 1 \lt 2C_s+C_d \leq 2 \\ 0 = & 2C_s+C_d \leq 1 \end{cases} \end{aligned}\]

VK_BLEND_OP_PINLIGHT_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} 0 = & 2C_s-1 \gt C_d \text{ and } C_s \lt 0.5 \\ 2C_s-1 = & 2C_s-1 \gt C_d \text{ and } C_s \geq 0.5 \\ 2C_s = & 2C_s-1 \leq C_d \text{ and } C_s \lt 0.5C_d \\ C_d = & 2C_s-1 \leq C_d \text{ and } C_s \geq 0.5C_d \end{cases} \end{aligned}\]

VK_BLEND_OP_HARDMIX_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D \begin{cases} 0 & C_s+C= _d \lt 1 \\ 1 & \text= {otherwise} \end{cases} \end{aligned}\]

When using one of the HSL blend operations in table Hue-Saturation-Luminosity Advanced Blend Operations as the blend operation, the RGB color components produ= ced by the function f are effectively obtained by converting both the non-premultiplied source and destination colors to the HSL (hue, saturation= , luminosity) color space, generating a new HSL color by selecting H, S, and = L components from the source or destination according to the blend operation, and then converting the result back to RGB. In the equations below, a blended RGB color is produced according to the following pseudocode:

  float minv3(vec3 c) {
    return min(min(c.r, c.g), c.b);
  }
  float maxv3(vec3 c) {
    return max(max(c.r, c.g), c.b);
  }
  float lumv3(vec3 c) {
    return dot(c, vec3(0.30, 0.59, 0.11));
  }
  float satv3(vec3 c) {
    return maxv3(c) - minv3(c);
  }

  // If any color components are outside [0,1], adj=
ust the color to
  // get the components in range.
  vec3 ClipColor(vec3 color) {
    float lum =3D lumv3(color);
    float mincol =3D minv3(color);
    float maxcol =3D maxv3(color);
    if (mincol < 0<=
/span>.0) {
      color =3D lum + ((color-lum)*lum) / (lum-mincol);
    }
    if (maxcol > 1<=
/span>.0) {
      color =3D lum + ((color-lum)*lum) / (maxcol-lum);
    }
    return color;
  }

  // Take the base RGB color <cbase> and over=
ride its luminosity
  // with that of the RGB color <clum>.
  vec3 SetLum(vec3 cbase, vec3 clum) {
    float lbase =3D lumv3(cbase);
    float llum =3D lumv3(clum);
    float ldiff =3D llum - lbase;
    vec3 color =3D cbase + vec3(ldiff);
    return ClipColor(color);
  }

  // Take the base RGB color <cbase> and over=
ride its saturation with
  // that of the RGB color <csat>.  The overr=
ide the luminosity of the
  // result with that of the RGB color <clum>=
.
  vec3 SetLumSat(vec3 cbase, vec3 csat, vec3 clum)
  {
    float minbase =3D minv3(cbase);
    float sbase =3D satv3(cbase);
    float ssat =3D satv3(csat);
    vec3 color;
    if (sbase > 0=
) {
      // Equivalent (modulo rounding errors) to set=
ting the
      // smallest (R,G,B) component to 0, the large=
st to <ssat>,
      // and interpolating the "middle" component b=
ased on its
      // original value relative to the smallest/la=
rgest.
      color =3D (cbase - minbase) * ssat / sbase;
    } else {
      color =3D vec3(0.0=
);
    }
    return SetLum(color, clum);
  }
Table 37. Hue-Saturation-Luminosity Advanced Blend= Operations
Mode Result

VK_BLEND_OP_HSL_HUE_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D SetLum= Sat(C_s,C_d,C_d) \end{aligned}\]

VK_BLEND_OP_HSL_SATURATION_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D SetLum= Sat(C_d,C_s,C_d) \end{aligned}\]

VK_BLEND_OP_HSL_COLOR_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D SetLum= (C_s,C_d) \end{aligned}\]

VK_BLEND_OP_HSL_LUMINOSITY_EXT

\[ \begin{aligned} (X,Y,Z) & =3D (1,1,1) \= \ f(C_s,C_d) & =3D SetLum= (C_d,C_s) \end{aligned}\]

When using one of the operations in table Additional RGB Blend Operations as the blend operation, the source and destination colors us= ed by these blending operations are interpreted according to srcPremultiplied and dstPremultiplied. The blending operations below are evaluated where the RGB source and destination color components are both considered to have been premultiplied by the corresponding A component.

\[\begin{aligned} (R_s', G_s', B_s') & =3D \begin{cases} (R_s, G_s, B_s) & \text{if srcPremultiplied is = VK\_TRUE} \\ (R_sA_s, G_sA_s, B_sA_s) & \text{if srcPremultiplied is = VK\_FALSE} \end{cases} \\ (R_d', G_d', B_d') & =3D \begin{cases} (R_d, G_d, B_d) & \text{if dstPremultiplied is = VK\_TRUE} \\ (R_dA_d, G_dA_d, B_dA_d) & \text{if dstPremultiplied is = VK\_FALSE} \end{cases} \end{aligned}\]
Table 38. Additional RGB Blend Operations
Mode Result

VK_BLEND_OP_PLUS_EXT

\[ \begin{aligned} (R,G,B,A) =3D ( & R_s'+= R_d', \\ & G_s'+G_= d', \\ & B_s'+B_= d', \\ & A_s+A_d= ) \end{aligned}\]

VK_BLEND_OP_PLUS_CLAMPED_EXT

\[ \begin{aligned} (R,G,B,A) =3D ( & min(1= ,R_s'+R_d'), \\ & min(1,G= _s'+G_d'), \\ & min(1,B= _s'+B_d'), \\ & min(1,A= _s+A_d)) \end{aligned}\]

VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT

\[ \begin{aligned} (R,G,B,A) =3D ( & min(m= in(1,A_s+A_d),R_s'+R_d'), \\ & min(min= (1,A_s+A_d),G_s'+G_d'), \\ & min(min= (1,A_s+A_d),B_s'+B_d'), \\ & min(1,A= _s+A_d)) \end{aligned}\]

VK_BLEND_OP_PLUS_DARKER_EXT

\[ \begin{aligned} (R,G,B,A) =3D ( & max(0= ,min(1,A_s+A_d)-((A_s-R_s')+(A_d-R_d'))), \\ & max(0,m= in(1,A_s+A_d)-((A_s-G_s')+(A_d-G_d'))), \\ & max(0,m= in(1,A_s+A_d)-((A_s-B_s')+(A_d-B_d'))), \\ & min(1,A= _s+A_d)) \end{aligned}\]

VK_BLEND_OP_MINUS_EXT

\[ \begin{aligned} (R,G,B,A) =3D ( & R_d'-= R_s', \\ & G_d'-G_= s', \\ & B_d'-B_= s', \\ & A_d-A_s= ) \end{aligned}\]

VK_BLEND_OP_MINUS_CLAMPED_EXT

\[ \begin{aligned} (R,G,B,A) =3D ( & max(0= ,R_d'-R_s'), \\ & max(0,G= _d'-G_s'), \\ & max(0,B= _d'-B_s'), \\ & max(0,A= _d-A_s)) \end{aligned}\]

VK_BLEND_OP_CONTRAST_EXT

\[ \begin{aligned} (R,G,B,A) =3D ( & \frac= {A_d}{2} + 2(R_d'-\frac{A_d}{2})(R_s'-\frac{A_s}{2}), \\ & \frac{A= _d}{2} + 2(G_d'-\frac{A_d}{2})(G_s'-\frac{A_s}{2}), \\ & \frac{A= _d}{2} + 2(B_d'-\frac{A_d}{2})(B_s'-\frac{A_s}{2}), \\ & A_d) \end{aligned}\]

VK_BLEND_OP_INVERT_OVG_EXT

\[ \begin{aligned} (R,G,B,A) =3D ( & A_s(1= -R_d') + (1-A_s)R_d', \\ & A_s(1-G= _d') + (1-A_s)G_d', \\ & A_s(1-B= _d') + (1-A_s)B_d', \\ & A_s+A_d= -A_sA_d) \end{aligned}\]

VK_BLEND_OP_RED_EXT

\[ \begin{aligned} (R,G,B,A) & =3D (R_s', = G_d', B_d', A_d) \end{aligned}\]

VK_BLEND_OP_GREEN_EXT

\[ \begin{aligned} (R,G,B,A) & =3D (R_d', = G_s', B_d', A_d) \end{aligned}\]

VK_BLEND_OP_BLUE_EXT

\[ \begin{aligned} (R,G,B,A) & =3D (R_d', = G_d', B_s', A_d) \end{aligned}\]

26.2. Logical Operations

The application can enable a logic= al operation between the fragment=E2=80=99s color values and the existing value in the framebuffer attachment. This logical operation is applied prior to updating the framebuffer attachment. Logical operations are applied only for signed and unsigned integer and normalized integer framebuffers. Logical operations are not applied to floating-point or sRGB format color attachments.

Logical operations are controlled by the logicOpEnable and logicOp members of VkPipe= lineColorBlendStateCreateInfo. If logicOpEnable is VK_TRUE, then a logical opera= tion selected by logicOp is applied between each color attachment and the fr= agment=E2=80=99s corresponding output value, and blending of all attachments is treated as i= f it were disabled. Any attachments using color formats for which logical operations are not supported simply pass through the color values unmodified. The logical operation is applied independently for each of the red, green, blue, and alpha components. The logicOp is selected from the following operations:

typedef enum VkLogicOp {
    VK_LOGIC_OP_CLEAR =3D 0,
    VK_LOGIC_OP_AND =3D 1,
    VK_LOGIC_OP_AND_REVERSE =3D 2,
    VK_LOGIC_OP_COPY =3D 3,
    VK_LOGIC_OP_AND_INVERTED =3D 4,
    VK_LOGIC_OP_NO_OP =3D 5,
    VK_LOGIC_OP_XOR =3D 6,
    VK_LOGIC_OP_OR =3D 7,
    VK_LOGIC_OP_NOR =3D 8,
    VK_LOGIC_OP_EQUIVALENT =3D 9,
    VK_LOGIC_OP_INVERT =3D 10,
    VK_LOGIC_OP_OR_REVERSE =3D 11,
    VK_LOGIC_OP_COPY_INVERTED =3D 12,
    VK_LOGIC_OP_OR_INVERTED =3D 13,
    VK_LOGIC_OP_NAND =3D 14,
    VK_LOGIC_OP_SET =3D 15,
} VkLogicOp;

The logical operations supported by Vulkan are summarized in the followi= ng table in which

  • =C2=AC is bitwise invert,

  • =E2=88=A7 is bitwise and,

  • =E2=88=A8 is bitwise or,

  • =E2=8A=95 is bitwise exclusive or,

  • s is the fragment=E2=80=99s Rs0, Gs0, Bs0 or As0 component value for the fragment output corresponding to the color attachment being updated, and

  • d is the color attachment=E2=80=99s R, G, B or A component value:

Table 39. Logical Operations
Mode Operation

VK_LOGIC_OP_CLEAR

0

VK_LOGIC_OP_AND

s =E2=88=A7 d

VK_LOGIC_OP_AND_REVERSE

s =E2=88=A7 =C2=AC d

VK_LOGIC_OP_COPY

s

VK_LOGIC_OP_AND_INVERTED

=C2=AC s =E2=88=A7 d

VK_LOGIC_OP_NO_OP

d

VK_LOGIC_OP_XOR

s =E2=8A=95 d

VK_LOGIC_OP_OR

s =E2=88=A8 d

VK_LOGIC_OP_NOR

=C2=AC (s =E2=88=A8 d)

VK_LOGIC_OP_EQUIVALENT

=C2=AC (s =E2=8A=95 d)

VK_LOGIC_OP_INVERT

=C2=AC d

VK_LOGIC_OP_OR_REVERSE

s =E2=88=A8 =C2=AC d

VK_LOGIC_OP_COPY_INVERTED

=C2=AC s

VK_LOGIC_OP_OR_INVERTED

=C2=AC s =E2=88=A8 d

VK_LOGIC_OP_NAND

=C2=AC (s =E2=88=A7 d)

VK_LOGIC_OP_SET

all= 1s

The result of the logical operation is then written to the color attachm= ent as controlled by the component write mask, described in Blend Operations.

27. Dispatching Commands

Dispatching commands (commands with Dispatch in th= e name) provoke work in a compute pipeline. Dispatching commands are recorded into a command buffer and when executed b= y a queue, will produce work which executes according to the bound compute pipeline. A compute pipeline must be bound to a com= mand buffer before any dispatch commands are recorded in that command buffer.

To record a dispatch, call:

void vkCmdDispatch(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    groupCountX,
    uint32_t                                    groupCountY,
    uint32_t                                    groupCountZ);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • groupCountX is the number of local workgroups to dispatch i= n the X dimension.

  • groupCountY is the number of local workgroups to dispatch i= n the Y dimension.

  • groupCountZ is the number of local workgroups to dispatch i= n the Z dimension.

When the command is executed, a global workgroup consisting of groupCountX =C3=97 groupCountY =C3=97 groupCountZ= local workgroups is assembled.

Valid Usage
  • groupCountX must be less tha= n or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 0]

  • groupCountY must be less tha= n or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 1]

  • groupCountZ must be less tha= n or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 2]

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_COMPUTE, wi= th a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • A valid compute pipeline must be bound to= the current command buffer with VK_PIPELINE_BIND_POINT_COMPUTE

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE, a push constant value must have been set for VK_PIPELINE_= BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for push constants with th= e one used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a unif= orm buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a stor= age buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IM= G as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_I= MG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, o= r VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_COMPUTE reads from or writes to any ima= ge or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_POINT_COMPUTE writes to any image or buffer, that image or buffer must not be an unprotecte= d image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the compute pipeline stage in the VkPipeline object bound to VK_PIPELINE_POINT_COMPUTE reads from any image= or buffer, the image or buffer must not be a= protected image or protected buffer.

Valid Usage (Implicit)
  • commandB= uffer must be a valid VkComm= andBuffer handle

  • commandB= uffer must be in the recording state

  • The VkComm= andPool that commandBuffer was allocated from must support compute operations

  • This command must only be called outside of a render pass instance<= /p>

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Com= pute

Com= pute

To record an indirect command dispatch, call:

void vkCmdDispatchIndirect(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    buffer,
    VkDeviceSize                                offset);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • buffer is the buffer containing dispatch parameters.

  • offset is the byte offset into buffer where pa= rameters begin.

vkCmdDispatchIndirect behaves similarly to v= kCmdDispatch except that the parameters are read by the device from a buffer during execution. The parameters of the dispatch are encoded in a VkDispatchIndirectCommand structure taken fr= om buffer starting at offset.

Valid Usage
  • If buffer is non-sparse then it must<= /strong> be bound completely and contiguously to a single VkDeviceMemory object

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_COMPUTE, wi= th a VkPipelineLayout that is compatible for set n, with t= he VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • A valid compute pipeline must be bound to= the current command buffer with VK_PIPELINE_BIND_POINT_COMPUTE

  • buffer must have been create= d with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

  • offset must be a multiple of= 4

  • The sum of offset and the size of VkDispatchIndirectComm= and must be less than or equal to the size of= buffer

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE, a push constant value must have been set for VK_PIPELINE_= BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for push constants with th= e one used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be = used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY= or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns with ImplicitLod, Dref or Proj in their n= ame, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be = used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructio= ns that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a unif= orm buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a stor= age buffer, it must not access values outside= of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IM= G as a result of this command, then the image view=E2=80=99s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_I= MG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, o= r VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_COMPUTE reads from or writes to any ima= ge or buffer, that image or buffer must not = be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage in the VkPipeline object bound to VK_PIPELINE_POINT_COMPUTE writes to any image or buffer, that image or buffer must not be an unprotecte= d image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeli= ne stage other than the compute pipeline stage in the VkPipeline object bound to VK_PIPELINE_POINT_COMPUTE reads from any image= or buffer, the image or buffer must not be a= protected image or protected buffer.

Valid Usage (Implicit)
  • = commandBuffer must be a valid VkCommandBuffer handle

  • buffer<= /code> must be a valid VkBuffer handle

  • = commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from <= strong class=3D"purple">must support compute operations

  • This command must only be called outside of a render pass in= stance

  • Both of buf= fer, and commandBuffer must have been created, allocated, or retrieved from the same VkDev= ice

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Com= pute

Com= pute

The VkDispatchIndirectCommand structure is defined as:

typedef struct VkDispatchIndire=
ctCommand {
    uint32_t    x;
    uint32_t    y;
    uint32_t    z;
} VkDispatchIndirectCommand;
  • x is the number of local workgroups to dispatch in the X dimension.

  • y is the number of local workgroups to dispatch in the Y dimension.

  • z is the number of local workgroups to dispatch in the Z dimension.

The members of VkDispatchIndirectCommand have the same mean= ing as the corresponding parameters of vkCmdDispatch.

Valid Usage
  • x must be less than or equal= to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 0]

  • y must be less than or equal= to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 1]

  • z must be less than or equal= to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 2]

To record a dispatch using non-zero base values for the components of WorkgroupId, call:

void vkCmdDispatchBase(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    baseGroupX,
    uint32_t                                    baseGroupY,
    uint32_t                                    baseGroupZ,
    uint32_t                                    groupCountX,
    uint32_t                                    groupCountY,
    uint32_t                                    groupCountZ);

or the equivalent command

void vkCmdDispatchBaseKHR(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    baseGroupX,
    uint32_t                                    baseGroupY,
    uint32_t                                    baseGroupZ,
    uint32_t                                    groupCountX,
    uint32_t                                    groupCountY,
    uint32_t                                    groupCountZ);
  • commandBuffer is the command buffer into which the command = will be recorded.

  • baseGroupX is the start value for the X component of WorkgroupId.

  • baseGroupY is the start value for the Y component of WorkgroupId.

  • baseGroupZ is the start value for the Z component of WorkgroupId.

  • groupCountX is the number of local workgroups to dispatch i= n the X dimension.

  • groupCountY is the number of local workgroups to dispatch i= n the Y dimension.

  • groupCountZ is the number of local workgroups to dispatch i= n the Z dimension.

When the command is executed, a global workgroup consisting of groupCountX =C3=97 groupCountY =C3=97 groupCountZ= local workgroups is assembled, with WorkgroupId values ranging from [baseGroup, baseGroup + groupCount) in each component. vkCmdDispatch is equivalent to vkCmdDispatchBase(0,0,0,groupCountX,groupCountY,groupCountZ).<= /p>

Valid Usage
  • All valid usage rules from vkCmdDispatch apply

  • baseGroupX must be less than VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 0]

  • baseGroupX must be less than VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 1]

  • baseGroupZ must be less than VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 2]

  • groupCountX must be less tha= n or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 0] minus baseGroupX

  • groupCountY must be less tha= n or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 1] minus baseGroupY

  • groupCountZ must be less tha= n or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[= 2] minus baseGroupZ

  • If any of baseGroupX, baseGroupY, or baseGr= oupZ are not zero, then the bound compute pipeline must have been created with the VK_PIPELINE_CREATE_DISPATCH_BASE flag.

Valid Usage (Implicit)
  • comm= andBuffer must be a valid Vk= CommandBuffer handle

  • comm= andBuffer must be in the recording state

  • The Vk= CommandPool that commandBuffer was allocated from must support compute operations

  • This command must only be called outside of a render pass instan= ce

Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Out= side

Com= pute

28. Device-Generated Commands

This chapter discusses the generation of command buffer content on the device. These principle steps are to be taken to generate commands on the device:

  • Make resource bindings accessible for the device via registering in an VkObjectTableNVX.

  • Define via VkIndirectCommandsLayoutNVX the sequence of comm= ands which should be generated.

  • Fill one or more VkBuffer with the appropriate content that= gets interpreted by VkIndirectCommandsLayoutNVX.

  • Reserve command space via vkCmdReserveS= paceForCommandsNVX in a secondary VkCommandBuffer where the generated commands should = be recorded.

  • Generate the actual commands via vkCmdProcessCo= mmandsNVX passing all required data.

Execution of such generated commands can either be triggered directly wi= th the generation process, or by executing the secondary VkCommandBuffer= that was chosen as optional target. The latter allows re-using generated commands as well. Similar to VkDescriptorSet, special care should be taken for the lifetime of resources referenced in VkObjectTableNVX, which ma= y be accessed at either generation or execution time.

vkCmdProcessCommandsNVX executes in a separ= ate logical pipeline from either graphics or compute. When generating commands into a secondary command buffer, the command generation must be explicitly synchronize= d against the secondary command buffer=E2=80=99s execution. When not using a secondary command buffer, the command generation is automatically synchronized against the command execution.

28.1. Features and Limitations

To query the support of related features and limitations, call:

void vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX(
    VkPhysicalDevice                            physicalDevice,
    VkDeviceGeneratedCommandsFeaturesNVX*       pFeatures,
    VkDeviceGeneratedCommandsLimitsNVX*         pLimits);
Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pFeatures must be a valid pointer to a VkDeviceGeneratedCommandsFeaturesNVX structure

  • pLimits must= be a valid pointer to a VkDeviceGeneratedCommandsLimitsNVX st= ructure

The VkDeviceGeneratedCommandsFeaturesNVX structure is defin= ed as:

typedef struct VkDeviceGenerate=
dCommandsFeaturesNVX {
    VkStructureType    sType;
    const void*        pNext;
    VkBool32           computeBindingPointSupport;
} VkDeviceGeneratedCommandsFeaturesNVX;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • computeBindingPointSupport specifies whether the VkObjectTableNVX supports entries with VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX bit set and VkIndirectCommandsLayoutNVX supports VK_PIPELINE_BIND_POINT_COMPUTE.

Valid Usage (Implicit)
  • sType must be VK_STRUCTUR= E_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX

  • pNext must be NULL=

The VkDeviceGeneratedCommandsLimitsNVX structure is defined= as:

typedef struct VkDeviceGenerate=
dCommandsLimitsNVX {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           maxIndirectCommandsLayoutTokenCount;
    uint32_t           maxObjectEntryCounts;
    uint32_t           minSequenceCountBufferOffsetAlignment;
    uint32_t           minSequenceIndexBufferOffsetAlignment;
    uint32_t           minCommandsTokenBufferOffsetAlignment;
} VkDeviceGeneratedCommandsLimitsNVX;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • maxIndirectCommandsLayoutTokenCount the maximum number of t= okens in VkIndirectCommandsLayoutNVX.

  • maxObjectEntryCounts the maximum number of entries per reso= urce type in VkObjectTableNVX.

  • minSequenceCountBufferOffsetAlignment the minimum alignment= for memory addresses optionally used in vkCmdProcessCommandsNVX.

  • minSequenceIndexBufferOffsetAlignment the minimum alignment= for memory addresses optionally used in vkCmdProcessCommandsNVX.

  • minCommandsTokenBufferOffsetAlignment the minimum alignment= for memory addresses optionally used in vkCmdProcessCommandsNVX.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_= TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX

  • pNext must be NULL

28.2. Binding Object Table

The device-side bindings are registered inside a table:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkObjectTableNVX)

This is required as the CPU-side object pointers, for example when bindi= ng a VkPipeline or VkDescriptorSet, cannot be used by = the device. The combination of VkObjectTableNVX and uint32_t = table indices stored inside a VkBuffer serve that purpose during device comm= and generation.

At creation time the table is defined with a fixed amount of registratio= n slots for the individual resource types. A detailed resource binding can then later be registered via vkRegisterObjectsNVX at any uint32_t= index below the allocated maximum.

28.2.1. Table Creation

To create object tables, call:

VkResult vkCreateO=
bjectTableNVX(
    VkDevice                                    device,
    const VkObjectTableCreateInfoNVX*     =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkObjectTableNVX*                           pObjectTable);
  • device is the logical device that creates the object table.=

  • pCreateInfo is a pointer to an instance of the VkObjectTableCreateInfoNVX structure containing parameters affecting creation of the table.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pObjectTable points to a VkObjectTableNVX= handle in which the resulting object table is returned.

Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • p= CreateInfo must be a valid pointer= to a valid VkObjectTableCreateInfoNVX structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllo= cationCallbacks structure

  • = pObjectTable must be a valid point= er to a VkObjectTableNVX handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkObjectTableCreateInfoNVX structure is defined as:

typedef struct VkObjectTableCre=
ateInfoNVX {
    VkStructureType                      sType;
    const void*                          pNext;
    uint32_t                             objectCount;
    const VkObjectEntryTypeNVX*          p=
ObjectEntryTypes;
    const uint32_t*                      p=
ObjectEntryCounts;
    const VkObjectEntryUsageFlagsNVX*    p=
ObjectEntryUsageFlags;
    uint32_t                             maxUniformBuffersPerDescriptor;
    uint32_t                             maxStorageBuffersPerDescriptor;
    uint32_t                             maxStorageImagesPerDescriptor;
    uint32_t                             maxSampledImagesPerDescriptor;
    uint32_t                             maxPipelineLayouts;
} VkObjectTableCreateInfoNVX;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • objectCount is the number of entry configurations that the = object table supports.

  • pObjectEntryTypes is an array of VkOb= jectEntryTypeNVX values providing the entry type of a given configuration.

  • pObjectEntryCounts is an array of counts of how many object= s can be registered in the table.

  • pObjectEntryUsageFlags is an array of bitmasks of VkObjectEntryUsageFlagBitsNVX specifying= the binding usage of the entry.

  • maxUniformBuffersPerDescriptor is the maximum number of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC used by any single registered VkDescriptorSet in this table.

  • maxStorageBuffersPerDescriptor is the maximum number of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC used by any single registered VkDescriptorSet in this table.

  • maxStorageImagesPerDescriptor is the maximum number of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER used by any single registered VkDescriptorSet in this table.

  • maxSampledImagesPerDescriptor is the maximum number of VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT used by any single registe= red VkDescriptorSet in this table.

  • maxPipelineLayouts is the maximum number of unique VkPipelineLayout used by any registered VkDescriptorSet<= /code> or VkPipeline in this table.

Valid Usage
  • If the VkDeviceGeneratedCommandsFeaturesNVX::computeBindingPoin= tSupport feature is not enabled, pObjectEntryUsageFlags must not contain VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX

  • Any value within pObjectEntryCounts m= ust not exceed VkDeviceGeneratedCommandsLimitsNVX::maxObjectEntryCounts=

  • maxUniformBuffersPerDescriptor must be within the limits supported by the device.

  • maxStorageBuffersPerDescriptor must be within the limits supported by the device.

  • maxStorageImagesPerDescriptor must be within the limits supported by the device.

  • maxSampledImagesPerDescriptor must be within the limits supported by the device.

Valid Usage (Implicit)

Possible values of elements of the VkObjectTableCreateInfoNVX::pObjectEn= tryTypes array, specifying the entry type of a configuration, are:

typedef enum VkObjectEntryTypeN=
VX {
    VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX =3D 0,
    VK_OBJECT_ENTRY_TYPE_PIPELINE_NVX =3D 1,
    VK_OBJECT_ENTRY_TYPE_INDEX_BUFFER_NVX =3D 2,
    VK_OBJECT_ENTRY_TYPE_VERTEX_BUFFER_NVX =3D 3,
    VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX =3D 4,
} VkObjectEntryTypeNVX;
  • VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX specifies a VkDescriptorSet resource entry that is registered via VkObjectTableDescriptorSetEntryNVX.

  • VK_OBJECT_ENTRY_TYPE_PIPELINE_NVX specifies a VkPipel= ine resource entry that is registered via VkObjectTablePipelineEntryNVX.

  • VK_OBJECT_ENTRY_TYPE_INDEX_BUFFER_NVX specifies a VkB= uffer resource entry that is registered via VkObjectTableIndexBufferEntryNVX.

  • VK_OBJECT_ENTRY_TYPE_VERTEX_BUFFER_NVX specifies a Vk= Buffer resource entry that is registered via VkObjectTableVertexBufferEntryNVX.

  • VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX specifies the resour= ce entry is registered via VkObjectTablePushConstantEntryNVX.

Bits which can be set in elements of t= he VkObjectTableCreateInfoNVX::pObjectEn= tryUsageFlags array, specifying binding usage of an entry, are:

typedef enum VkObjectEntryUsage=
FlagBitsNVX {
    VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX =3D 0x000000=
01,
    VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX =3D 0x0000000=
2,
} VkObjectEntryUsageFlagBitsNVX;
  • VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX specifies that the r= esource is bound to VK_PIPELINE_BIND_POINT_GRAPHICS

  • VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX specifies that the re= source is bound to VK_PIPELINE_BIND_POINT_COMPUTE

typedef VkFlags VkObjectEntryUsageFlagsNVX;

VkObjectEntryUsageFlagsNVX is a bitmask type for setting a = mask of zero or more VkObjectEntryUsageFlagBitsNVX.

To destroy an object table, call:

void vkDestroyObjectTableNVX(
    VkDevice                                    device,
    VkObjectTableNVX                            objectTable,
    const VkAllocationCallbacks*          =
      pAllocator);
Valid Usage
  • All submitted commands that refer to objectTable must have completed execution.

  • If VkAllocationCallbacks were provided when objectTable<= /code> was created, a compatible set of callbacks must be provided here.

  • If no VkAllocationCallbacks were provided when objectTab= le was created, pAllocator must= be NULL.

Valid Usage (Implicit)
  • devic= e must be a valid VkDevice handle

  • = objectTable must be a valid = VkObjectTableNVX handle

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAll= ocationCallbacks structure

  • obj= ectTable must have been created, a= llocated, or retrieved from device

Host Synchronization
  • Host access to objectTable must be externally synchronized

28.2.2. Registering Objects

Resource bindings of Vulkan objects are registered at an arbitrary uint32_t index within an object table. As long as the object table references such objects, they must not be deleted.

VkResult vkRegiste=
rObjectsNVX(
    VkDevice                                    device,
    VkObjectTableNVX                            objectTable,
    uint32_t                                    objectCount,
    const VkObjectTableEntryNVX* const*         ppObjectTableEntries,
    const uint32_t*                       =
      pObjectIndices);
  • device is the logical device that creates the object table.=

  • objectTable is the table for which the resources are regist= ered.

  • objectCount is the number of resources to register.

  • ppObjectTableEntries provides an array for detailed binding informations, each array element is a pointer to a struct of type VkObjectTablePipelineEntryNVX, VkObjectTableDescriptorSetEntryNVX, VkObjectTableVertexBufferEntryNVX, VkObjectTableIndexBufferEntryNVX or VkObjectTablePushConstantEntryNVX (see below for details).

  • pObjectIndices are the indices at which each resource is registered.

Valid Usage
  • The contents of pObjectTableEntry mus= t yield plausible bindings supported by the device.

  • At any pObjectIndices there must not be a registered resource already.

  • Any value inside pObjectIndices must<= /strong> be below the appropriate VkObjectTableCreateInfoNVX::pObjectEntryCounts li= mits provided at objectTable creation time.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • obj= ectTable must be a valid VkO= bjectTableNVX handle

  • = ppObjectTableEntries must be= a valid pointer to an array of objectCount valid VkObje= ctTableEntryNVX structures

  • = pObjectIndices must be a valid poi= nter to an array of objectCount uint32_t values

  • o= bjectCount must be greater than 0

  • object= Table must have been created, allo= cated, or retrieved from device

Host Synchronization
  • Host access to objectTable must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Common to all resource entries are:

typedef struct VkObjectTableEnt=
ryNVX {
    VkObjectEntryTypeNVX          type;
    VkObjectEntryUsageFlagsNVX    flags;
} VkObjectTableEntryNVX;
  • type defines the entry type

  • flags defines which VkPipelineBindPoin= t the resource can be used with. Some entry types allow only a single flag to be set.

Valid Usage (Implicit)
typedef struct VkObjectTablePip=
elineEntryNVX {
    VkObjectEntryTypeNVX          type;
    VkObjectEntryUsageFlagsNVX    flags;
    VkPipeline                    pipeline;
} VkObjectTablePipelineEntryNVX;
  • pipeline specifies the VkPipeline that this= resource entry references.

Valid Usage
  • type must be VK_OBJECT= _ENTRY_TYPE_PIPELINE_NVX

Valid Usage (Implicit)
typedef struct VkObjectTableDes=
criptorSetEntryNVX {
    VkObjectEntryTypeNVX          type;
    VkObjectEntryUsageFlagsNVX    flags;
    VkPipelineLayout              pipelineLayout;
    VkDescriptorSet               descriptorSet;
} VkObjectTableDescriptorSetEntryNVX;
Valid Usage
  • type must be VK_OBJECT= _ENTRY_TYPE_DESCRIPTOR_SET_NVX

Valid Usage (Implicit)
  • type must be a valid VkObjectEntryTypeNVX value

  • <= code>flags must be a valid combina= tion of VkObjectEntryUsageFlagBitsNVX va= lues

  • = flags must not be 0

  • pipelineLayout must = be a valid VkPipelineLayout handle

  • descriptorSet must be= a valid VkDescriptorSet handle

  • Both= of descriptorSet, and pipelineLayout must have been created, allocated, or retrieved from= the same VkDevice

typedef struct VkObjectTableVer=
texBufferEntryNVX {
    VkObjectEntryTypeNVX          type;
    VkObjectEntryUsageFlagsNVX    flags;
    VkBuffer                      buffer;
} VkObjectTableVertexBufferEntryNVX;
  • buffer specifies the VkBuffer that can be bou= nd as vertex bufer

Valid Usage
  • type must be VK_OBJECT= _ENTRY_TYPE_VERTEX_BUFFER_NVX

Valid Usage (Implicit)
typedef struct VkObjectTableInd=
exBufferEntryNVX {
    VkObjectEntryTypeNVX          type;
    VkObjectEntryUsageFlagsNVX    flags;
    VkBuffer                      buffer;
    VkIndexType                   indexType;
} VkObjectTableIndexBufferEntryNVX;
  • buffer specifies the VkBuffer that can be bou= nd as index buffer

  • indexType specifies the VkIndexType used w= ith this index buffer

Valid Usage
  • type must be VK_OBJECT= _ENTRY_TYPE_INDEX_BUFFER_NVX

Valid Usage (Implicit)
typedef struct VkObjectTablePus=
hConstantEntryNVX {
    VkObjectEntryTypeNVX          type;
    VkObjectEntryUsageFlagsNVX    flags;
    VkPipelineLayout              pipelineLayout;
    VkShaderStageFlags            stageFlags;
} VkObjectTablePushConstantEntryNVX;
Valid Usage
  • type must be VK_OBJECT= _ENTRY_TYPE_PUSH_CONSTANT_NVX

Valid Usage (Implicit)

Use the following command to unregister resources from an object table:<= /p>

VkResult vkUnregis=
terObjectsNVX(
    VkDevice                                    device,
    VkObjectTableNVX                            objectTable,
    uint32_t                                    objectCount,
    const VkObjectEntryTypeNVX*           =
      pObjectEntryTypes,
    const uint32_t*                       =
      pObjectIndices);
  • device is the logical device that creates the object table.=

  • objectTable is the table from which the resources are unregistered.

  • objectCount is the number of resources being removed from t= he object table.

  • pObjectEntryType provides an array of VkObjectEntryTypeNVX for the resources being removed.

  • pObjectIndices provides the array of object indices to be r= emoved.

Valid Usage
  • At any pObjectIndices there must be a registered resource already.

  • The pObjectEntryTypes of the resource at pObjectIndices<= /code> must match.

  • All operations on the device using the registered resource must have been completed.

Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • o= bjectTable must be a valid V= kObjectTableNVX handle

  • <= code>pObjectEntryTypes must be a v= alid pointer to an array of objectCount valid VkObjectEntryTypeNVX values

  • pObjectIndices must be a valid p= ointer to an array of objectCount uint32_t values=

  • objectCount must be greater than = 0

  • obje= ctTable must have been created, al= located, or retrieved from device

Host Synchronization
  • Host access to objectTable must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

28.3. Indirect Commands Layout

The device-side command generation happens through an iterative processi= ng of an atomic sequence comprised of command tokens, which are represented by= :

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX)

28.3.1. Tokenized Command Processi= ng

The processing is in principle illustrated below:

void cmdProcessSequence(cmd, objectTable, indirectCommandsLayo=
ut, pIndirectCommandsTokens, s)
{
  for (c =3D 0; c < indirectCommandsLayout.tokenCount; c++)
  {
    indirectCommandsLayout.pTokens[c].command (cmd, objectTable, pIndirectC=
ommandsTokens[c], s);
  }
}

void cmdProcessAllSequences(cmd, objectTab=
le, indirectCommandsLayout, pIndirectCommandsTokens, sequencesCount)
{
  for (s =3D 0; s < sequencesCount; s++)
  {
    cmdProcessSequence(cmd, objectTable, indirectCommandsLayout, pIndirectC=
ommandsTokens, s);
  }
}

The processing of each sequence is considered stateless, therefore all s= tate changes must occur prior work provoking c= ommands within the sequence. A single sequence is either strictly targeting VK_PIPELINE_BIND_POINT_GRAPHICS or VK_PIPELINE_BIND_POINT_COMPUTE.

The primary input data for each token is provided through VkBuffer= content at command generation time using vkCmdProc= essCommandsNVX, however some functional arguments, for example binding sets, are specified at layout creation time. The input size is different for each token.

Possible values of those elements of the VkIndirectCommandsLayoutCreateInfoNV= X::pTokens array which specify command tokens (other elements of the array specify command parameters) are:

typedef enum VkIndirectCommands=
TokenTypeNVX {
    VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX =3D 0,
    VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX =3D 1,
    VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX =3D 2,
    VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX =3D 3,
    VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX =3D 4,
    VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX =3D 5,
    VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX =3D 6<=
/span>,
    VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX =3D 7,
} VkIndirectCommandsTokenTypeNVX;
Table 40. Supported indirect command tokens
Token type Equivalent command

VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX

vkCmdBindPipeline

VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX

vkCmdBindDescriptorSets

VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX

vkCmdBindIndexBuffer

VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX

vkCmdBindVertexBuffers

VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX

vkCmdPushConstants

VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX

vkCmdDrawIndexedIndirect

VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX

vkCmdDrawIndirect

VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX

vkCmdDispatchIndirect

The VkIndirectCommandsLayoutTokenNVX structure specifies de= tails to the function arguments that need to be known at layout creation time:

typedef struct VkIndirectComman=
dsLayoutTokenNVX {
    VkIndirectCommandsTokenTypeNVX    tokenType;
    uint32_t                          bindingUnit;
    uint32_t                          dynamicCount;
    uint32_t                          divisor;
} VkIndirectCommandsLayoutTokenNVX;
  • type specifies the token command type.

  • bindingUnit has a different meaning depending on the type, = please refer pseudo code further down for details.

  • dynamicCount has a different meaning depending on the type,= please refer pseudo code further down for details.

  • divisor defines the rate at which the input data buffers ar= e accessed.

Valid Usage
  • bindingUnit must stay within= device supported limits for the appropriate commands.

  • dynamicCount must stay withi= n device supported limits for the appropriate commands.

  • divisor must be greater than= 0 and a power of two.

Valid Usage (Implicit)
  • = tokenType must be a valid <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kIndirectCommandsTokenTypeNVX">VkIndirectCommandsTokenTypeNVX value

The VkIndirectCommandsTokenNVX structure specifies the inpu= t data for a token at processing time.

typedef struct VkIndirectComman=
dsTokenNVX {
    VkIndirectCommandsTokenTypeNVX    tokenType;
    VkBuffer                          buffer;
    VkDeviceSize                      offset;
} VkIndirectCommandsTokenNVX;
  • tokenType specifies the token command type.

  • buffer specifies the VkBuffer storing the fun= ctional arguments for each squence. These argumetns can be written by the device.

  • offset specified an offset into buffer where t= he arguments start.

Valid Usage
  • The buffer=E2=80=99s usage flag must<= /strong> have the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set.

  • The offset must be aligned t= o VkDeviceGeneratedCommandsLimitsNVX::minCommandsTokenBuff= erOffsetAlignment.

Valid Usage (Implicit)

The following code provides detailed information on how an individual sequence is processed:

void cmdProcessSequence(cmd, objectTable, indirectCommandsLayo=
ut, pIndirectCommandsTokens, s)
{
  for (uint32_t c =3D 0; c < indirectCommandsLayout.tokenCount; c++){
    input   =3D pIndirectCommandsTokens[c];
    i       =3D s / indirectCommandsLayout.pTokens[c].divisor;

    switch(input.type){
      VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX:
        size_t    stride  =3D sizeof(uint32_=
t);
        uint32_t* data    =3D input.buffer.pointer( input.offset + stride *=
 i );
        uint32_t  object  =3D data[0];

        vkCmdBindPipeline(cmd, indirectCommandsLayout.pipelineBindPoint,
          objectTable.pipelines[ object ].pipeline);
      break;

      VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_=
NVX:
        size_t    stride  =3D sizeof(uint32_=
t) + sizeof(uint32_t) * indirectCommandsLayo=
ut.pTokens[c].dynamicCount;
        uint32_t* data    =3D input.buffer.pointer( input.offset + stride *=
 i);
        uint32_t  object  =3D data[0];

        vkCmdBindDescriptorSets(cmd, indirectCommandsLayout.pipelineBindPoi=
nt,
          objectTable.descriptorsets[ object ].layout,
          indirectCommandsLayout.pTokens[ c ].bindingUnit,
          1, &objectTable.descriptorsets=
[ object ].descriptorSet,
          indirectCommandsLayout.pTokens[ c ].dynamicCount, data + 1);
      break;

      VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_N=
VX:
        size_t    stride  =3D sizeof(uint32_=
t) + indirectCommandsLayout.pTokens[c].dynamicCount;
        uint32_t* data    =3D input.buffer.pointer( input.offset + stride *=
 i );
        uint32_t  object  =3D data[0];

        vkCmdPushConstants(cmd,
          objectTable.pushconstants[ object ].layout,
          objectTable.pushconstants[ object ].stageFlags,
          indirectCommandsLayout.pTokens[ c ].bindingUnit, indirectCommands=
Layout.pTokens[c].dynamicCount, data + 1);
      break;

      VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV=
X:
        size_t   s tride  =3D sizeof(uint32_=
t) + sizeof(uint32_t) * indirectCommandsLayo=
ut.pTokens[c].dynamicCount;
        uint32_t* data    =3D input.buffer.pointer( input.offset + stride *=
 i );
        uint32_t  object  =3D data[0];

        vkCmdBindIndexBuffer(cmd,
          objectTable.vertexbuffers[ object ].buffer,
          indirectCommandsLayout.pTokens[ c ].dynamicCount ? data[1] : 0,
          objectTable.vertexbuffers[ object ].indexType);
      break;

      VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_N=
VX:
        size_t    stride  =3D sizeof(uint32_=
t) + sizeof(uint32_t) * indirectCommandsLayo=
ut.pTokens[c].dynamicCount;
        uint32_t* data    =3D input.buffer.pointer( input.offset + stride *=
 i );
        uint32_t  object  =3D data[0];

        vkCmdBindVertexBuffers(cmd,
          indirectCommandsLayout.pTokens[ c ].bindingUnit, 1,
          &objectTable.vertexbuffers[ object ].buffer,
          indirectCommandsLayout.pTokens[ c ].dynamicCount ? data + 1 : {0}); // device size handled as uint32_t
      break;

      VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV=
X:
        vkCmdDrawIndexedIndirect(cmd,
          input.buffer,
          sizeof(VkDrawIndexedIndirectComman=
d) * i + input.offset, 1, 0);
      break;

      VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX:
        vkCmdDrawIndirect(cmd,
          input.buffer,
          sizeof(VkDrawIndirectCommand) * i =
 + input.offset, 1, =
0);
      break;

      VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX:
        vkCmdDispatchIndirect(cmd,
          input.buffer,
          sizeof(VkDispatchIndirectCommand) =
* i  + input.offset);
      break;
    }
  }
}

28.3.2. Creation and Deletion

Indirect command layouts are created by:

VkResult vkCreateI=
ndirectCommandsLayoutNVX(
    VkDevice                                    device,
    const VkIndirectCommandsLayoutCreateIn=
foNVX* pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkIndirectCommandsLayoutNVX*                pIndirectCommandsLayout);
  • device is the logical device that creates the indirect comm= and layout.

  • pCreateInfo is a pointer to an instance of the VkIndirectCommandsLayoutCreateInfoNVX structure containing parameters affecting creation of the indirect command layout.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pIndirectCommandsLayout points to a VkIndirectCommandsLayoutNVX handle in which the resulting indi= rect command layout is returned.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkIndirectCommandsLayoutCreateInfoNVX structure is defi= ned as:

typedef struct VkIndirectComman=
dsLayoutCreateInfoNVX {
    VkStructureType                            sType;
    const void*                                pNext;
    VkPipelineBindPoint                        pipelineBindPoint;
    VkIndirectCommandsLayoutUsageFlagsNVX      flags;
    uint32_t                                   tokenCount;
    const VkIndirectCommandsLayoutTokenNVX=
*    pTokens;
} VkIndirectCommandsLayoutCreateInfoNVX;

The following code illustrates some of the key flags:

void cmdProcessAllSequences(cmd, objectTable, indirectCommands=
Layout, pIndirectCommandsTokens, sequencesCount, indexbuffer, indexbufferof=
fset)
{
  for (s =3D 0; s < sequencesCount; s++)
  {
    sequence =3D s;

    if (indirectCommandsLayout.flags & V=
K_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX) {
      sequence =3D incoherent_implementation_dependent_permutation[ sequenc=
e ];
    }
    if (indirectCommandsLayout.flags & V=
K_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX) {
      sequence =3D indexbuffer.load_uint32( sequence * sizeof(uint32_t) + indexbufferoffset);
    }

    cmdProcessSequence( cmd, objectTable, indirectCommandsLayout, pIndirect=
CommandsTokens, sequence );
  }
}
Valid Usage
  • tokenCount must be greater t= han 0 and below VkDeviceGeneratedCommandsLimitsNVX::maxIndirectCommandsL= ayoutTokenCount

  • If the VkDeviceGeneratedCommandsFeaturesNVX::computeBindingPoin= tSupport feature is not enabled, then pipelineBindPoint must not be VK_PIPELINE_BIND_POINT_COMPUTE

  • If pTokens contains an entry of VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX it must be the first element of the array and there must be on= ly a single element of such token type.

  • All state binding tokens in pTokens m= ust occur prior work provoking tokens (VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX, VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX, VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX).

  • The content of pTokens must = include one single work provoking token that is compatible with the pipelineBindPoint.

Valid Usage (Implicit)

Bits which can be set in VkIndirectCommandsLayoutCreateInfoNV= X::flags, specifying usage hints of an indirect command layout, are:

typedef enum VkIndirectCommands=
LayoutUsageFlagBitsNVX {
    VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX =3D 0x00000001,
    VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX =3D 0x00000002,
    VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX =3D 0x00000004,
    VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX =3D 0x00000008,
} VkIndirectCommandsLayoutUsageFlagBitsNVX;
  • VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX specifies that the processing of sequences can happen at an implementation-dependent order, which is not guaranteed to be coherent across multiple invocations.

  • VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX specifies that there is likely a high difference between allocated number of sequences and actually used.

  • VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX specifies that there are likely many draw or dispatch calls that are zero-sized (zero grid dimension, no primitives to render).

  • VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX specifies that the input data for the sequences is not implicitly indexed from 0..sequencesUsed but a user provided VkBuffer encoding the index is provided.

typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNVX;<=
/pre>

VkIndirectCommandsLayoutUsageFlagsNVX is a bitmask type for= setting a mask of zero or more VkIndirectCo= mmandsLayoutUsageFlagBitsNVX.

Indirect command layouts are destroyed by:

void vkDestroyIndirectCommandsLayoutNVX(
    VkDevice                                    device,
    VkIndirectCommandsLayoutNVX                 indirectCommandsLayout,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device that destroys the layout.

  • indirectCommandsLayout is the table to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • All submitted commands that refer to indirectCommandsLayout must have completed execution

  • If VkAllocationCallbacks were provided when objectTable<= /code> was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when objectTab= le was created, pAllocator must= be NULL

Valid Usage (Implicit)

28.4. Indirect Commands Generation=

Command space for generated commands recorded into a secondary command buffer must be reserved by calling:

void vkCmdReserveSpaceForCommandsNVX(
    VkCommandBuffer                             commandBuffer,
    const VkCmdReserveSpaceForCommandsInfo=
NVX*  pReserveSpaceInfo);
  • commandBuffer is the secondary command buffer in which the = space for device-generated commands is reserved.

  • pProcessCommandsInfo is a pointer to an instance of the vkCmdReserveSpaceForCommandsNVX struct= ure containing parameters affecting the reservation of command buffer space.

Valid Usage
  • The provided commandBuffer must not have had a prior space reservation since its creation or the last reset.

  • The state of the commandBuffer must be legal to execute all commands within the sequence provided by the indirectCommandsLayout member of pProcessCommandsInfo.

Valid Usage (Implicit)
Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Sec= ondary

Ins= ide

Gra= phics
Compute

typedef struct VkCmdReserveSpac=
eForCommandsInfoNVX {
    VkStructureType                sType;
    const void*                    pNext;
    VkObjectTableNVX               objectTable;
    VkIndirectCommandsLayoutNVX    indirectCommandsLayout;
    uint32_t                       maxSequencesCount;
} VkCmdReserveSpaceForCommandsInfoNVX;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • objectTable is the VkObjectTableNVX t= o be used for the generation process. Only registered objects at the time vkCmdReserveSpaceForCommandsNVX is cal= led, will be taken into account for the reservation.

  • indirectCommandsLayout is the = VkIndirectCommandsLayoutNVX that must also be used at generation time= .

  • maxSequencesCount is the maximum number of sequences for wh= ich command buffer space will be reserved.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX

  • pNext must be NULL<= /p>

  • objectTable must be a = valid VkObjectTableNVX handle

  • indirectCommandsLayout must be a valid VkIndirectCommandsLayoutNVX handle=

  • Bot= h of indirectCommandsLayout, and objectTable must have been created, allocated, or retriev= ed from the same VkDevice

Host Synchronization
  • Host access to objectTable must be externally synchronized

The generated commands will behave as if they were recorded within the c= all to vkCmdReserveSpaceForCommandsNVX, that means they can inheri= t state defined in the command buffer prior this call. However, given the stateless nature of the generated sequences, they will not affect commands after the reserved space. Treat the state that can be affected by t= he provided VkIndirectCommandsLayoutNVX as undefined.

The actual generation on the device is handled with:

void vkCmdProcessCommandsNVX(
    VkCommandBuffer                             commandBuffer,
    const VkCmdProcessCommandsInfoNVX*    =
      pProcessCommandsInfo);
  • commandBuffer is the primary command buffer in which the generation process takes space.

  • pProcessCommandsInfo is a pointer to an instance of the VkCmdProcessCommandsInfoNVX structure cont= aining parameters affecting the processing of commands.

Valid Usage (Implicit)
Host Synchronization
  • Host access to commandBuffer must<= /strong> be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Ins= ide

Gra= phics
Compute

typedef struct VkCmdProcessComm=
andsInfoNVX {
    VkStructureType                      sType;
    const void*                          pNext;
    VkObjectTableNVX                     objectTable;
    VkIndirectCommandsLayoutNVX          indirectCommandsLayout;
    uint32_t                             indirectCommandsTokenCount;
    const VkIndirectCommandsTokenNVX*    p=
IndirectCommandsTokens;
    uint32_t                             maxSequencesCount;
    VkCommandBuffer                      targetCommandBuffer;
    VkBuffer                             sequencesCountBuffer;
    VkDeviceSize                         sequencesCountOffset;
    VkBuffer                             sequencesIndexBuffer;
    VkDeviceSize                         sequencesIndexOffset;
} VkCmdProcessCommandsInfoNVX;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • objectTable is the VkObjectTableNVX t= o be used for the generation process. Only registered objects at the time vkCmdReserveSpaceForCommandsNVX is cal= led, will be taken into account for the reservation.

  • indirectCommandsLayout is the = VkIndirectCommandsLayoutNVX that provides the command sequence to generate.

  • indirectCommandsTokenCount defines the number of input toke= ns used.

  • pIndirectCommandsTokens provides an array of VkIndirectCommandsTokenNVX that reference t= he input data for each token command.

  • maxSequencesCount is the maximum number of sequences for wh= ich command buffer space will be reserved. If sequencesCountBuffer is VK_NULL_HANDLE,= this is also the actual number of sequences generated.

  • targetCommandBuffer can b= e the secondary VkCommandBuffer in which the commands should be recorded. If targetCommandBuffer is NULL an implicit reserv= ation as well as execution takes place on the processing VkCommandBuffer.

  • sequencesCountBuffer can = be VkBuffer from which the actual amount of sequences is sourced from as uint32_t value.

  • sequencesCountOffset is the byte offset into sequencesCountBuffer where the count value is stored.

  • sequencesIndexBuffer must= be set if indirectCommandsLayout=E2=80=99s VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT is set= and provides the used sequence indices as uint32_t array. Otherwise it must be VK_N= ULL_HANDLE.

  • sequencesIndexOffset is the byte offset into sequencesIndexBuffer where the index values start.

Valid Usage (Implicit)
  • sType<= /code> must be VK_STRUCTURE_TYPE_CM= D_PROCESS_COMMANDS_INFO_NVX

  • pNext<= /code> must be NULL

  • objectTable must be a valid VkObjectTableNVX handle

  • indirectCommandsLayout must<= /strong> be a valid VkIndirectCommandsLayoutNVX handle

  • pIndirectCommandsTokens mus= t be a valid pointer to an array of indirectCommandsTokenCou= nt valid VkIndirectCommandsTokenNVX structures

  • If targetCommandBuffer is not NULL, t= argetCommandBuffer must be a valid= VkCommandBuffer handle

  • If sequencesCountBuffer is not VK_NULL_= HANDLE, sequencesCountBuffer must= be a valid VkBuffer handle

  • If sequencesIndexBuffer is not VK_NULL_= HANDLE, sequencesIndexBuffer must= be a valid VkBuffer handle

  • indirectCommandsTokenCount must be greater than 0

  • Each of indirectCommandsLayout, objectTable, sequences= CountBuffer, sequencesIndexBuffer, and targetComm= andBuffer that are valid handles must have been created, allocated, or retrieved from the same VkDevice=

Host Synchronization
  • Host access to objectTable must be externally synchronized

  • Host access to targetCommandBuffer must be externally synchronized

Referencing the functions defined in Indirect Command= s Layout, vkCmdProcessCommandsNVX behaves as:

// For targetCommandBuffers the existing reservedSpace is reset & o=
verwritten.

VkCommandBuffer cmd =3D targetCommandBuffer ?
      targetCommandBuffer.reservedSpace :
      commandBuffer;

uint32_t sequencesCount =3D sequencesCountBuffer ?
      min(maxSequencesCount, sequencesCountBuffer.load_uint32(sequencesCoun=
tOffset) :
      maxSequencesCount;


cmdProcessAllSequences(cmd, objectTable,
                       indirectCommandsLayout, pIndirectCommandsTokens,
                       sequencesCount,
                       sequencesIndexBuffer, sequencesIndexOffset);

// The stateful commands within indirectCommandsLay=
out will not
// affect the state of subsequent commands in the t=
arget
// command buffer (cmd)
Note

It is important to note that the state that may be affected through generated commands must be considered und= efined for the commands following them. It is not possible to setup generated state and provoking work that uses this state outside of the generated sequence.

29. Sparse Resources

As documented in Resource Memory Association, VkBuffer and VkImage resources in Vulkan must be bound completely and contiguously to a single VkDeviceMemory object. This binding must be done before the reso= urce is used, and the binding is immutable for the lifetime of the resource.

Sparse resources relax these restrictions and provide these add= itional features:

  • Sparse resources can be bound non-cont= iguously to one or more VkDeviceMemory allocations.

  • Sparse resources can be re-bound to di= fferent memory allocations over the lifetime of the resource.

  • Sparse resources can have descriptors = generated and used orthogonally with memory binding commands.

29.1. Sparse Resource Featur= es

Sparse resources have several features that mus= t be enabled explicitly at resource creation time. The features are enabled by including bits in the flags parame= ter of VkImageCreateInfo or VkBufferCre= ateInfo. Each feature also has one or more corresponding feature enables specified i= n VkPhysicalDeviceFeatures.

  • Sparse binding is the base feature, and provides the following capabilities:

    • Resources can be bound at some defined= (sparse block) granularity.

    • The entire resource must be bound to m= emory before use regardless of regions actually accessed.

    • No specific mapping of image region to memory offset is defined, i.e. the location that each texel corresponds to in memory is implementation-dependent.

    • Sparse buffers have a well-defined mapping of buffer range to memory range, where an offset into a range of the buffer that is bound to a single contiguous range of memory corresponds to an identical offset within that range of memory.

    • Requested via the VK_IMAGE_CREATE_SPARSE_BINDING_BIT and VK_BUFFER_CREATE_SPARSE_BINDING_BIT bits.

    • A sparse image created using VK_IMAGE_CREATE_SPARSE_BINDING_BIT (but not VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) supports all formats that non-sparse usage supports, and supports both VK_IMAGE_TILING_OPTIMAL and VK_IMAGE_TILING_LINEAR tiling.

  • Sparse Residency builds on (and requires) the sparseBindi= ng feature. It includes the following capabilities:

    • Resources do not have to be completely bound to memory before use on the device.

    • Images have a prescribed sparse image block layout, allowing specific rectangular regions of the image to be bound to specific offsets in memory allocations.

    • Consistency of access to unbound regions of the resource is defined by the absence or presence of VkPhysicalDeviceSparseProperties::residencyNonResidentSt= rict. If this property is present, accesses to unbound regions of the resource are well defined and behave as if the data bound is populated with all zeros; writes are discarded. When this property is absent, accesses are considered safe, but reads will return undefined values.

    • Requested via the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT and VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT bits.

    • Sparse residency suppor= t is advertised on a finer grain via the following features:

      • sparseResidencyBuffer: Support for creating VkBuffer objects with the VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT.

      • sparseResidencyImage2D: Support for creating 2D single-sampled VkImage objects with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

      • sparseResidencyImage3D: Support for creating 3D VkImage objects with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

      • sparseResidency2Samples= : Support for creating 2D VkImage objects with 2 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

      • sparseResidency4Samples= : Support for creating 2D VkImage objects with 4 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

      • sparseResidency8Samples= : Support for creating 2D VkImage objects with 8 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

      • sparseResidency16Sampl= es: Support for creating 2D VkImage objects with 16 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

      Implementations supporting sparseResidencyImage2D are only = required to support sparse 2D, single-sampled images. Support for sparse 3D and MSAA images is optional<= /strong> and can be enabled via sparseResidencyImage3D, sparseResidency2Samples, sparseResidency4Samples, sparseResidency8Samples,= and sparseResidency16Samples.

    • A sparse image created using VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT<= /code> supports all non-compressed color formats with power-of-two element size that non-sparse usage supports. Additional formats may also be supported = and can be queried via vkGetPhysicalDeviceSparseIm= ageFormatProperties. VK_IMAGE_TILING_LINEAR tiling is not supported.

  • Sparse aliasing provides the following capability that can be enab= led per resource:

    Allows physical memory ranges to be shared between multiple locations in= the same sparse resource or between multiple sparse resources, with each bindin= g of a memory location observing a consistent interpretation of the memory contents.

    See Sparse Memory Aliasing for = more information.

29.2. Sparse Buffers and Fully-Resid= ent Images

Both VkBuffer and VkImage objects created with= the VK_IMAGE_CREATE_SPARSE_BINDING_BIT or VK_BUFFER_CREATE_SPARSE_BINDING_BIT bits can be thought of as a linear region of address space. In the VkImage case if VK_IMAGE_CREATE_SPARSE_RESIDENCY_= BIT is not used, this linear region is entirely opaque, meaning that there is no application-visible mapping between texel location and memory offset.

Unless VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT are also used, the entir= e resource must be bound to one or more VkDeviceMemory objects before use.

29.2.1. Spars= e Buffer and Fully-Resident Image Block Size

The sparse block size in bytes for sparse buffers and fully-resident ima= ges is reported as VkMemoryRequirements::alignment. alignment represents both the memory alignment requirement and= the binding granularity (in bytes) for sparse resources.

29.3. Sparse Partially-R= esident Buffers

VkBuffer objects created with the VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT bit allow the buffer to = be made only partially resident. Partially resident VkBuffer objects are allocated and bound identically to VkBuffer objects using only the VK_BUFFER_CREATE_SPARSE_BINDING_BIT feature. The only difference is the ability for some regions of the buffer to be unbound during device use.

29.4. Sparse Partially-Re= sident Images

VkImage objects created with the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT bit allow specific rectan= gular regions of the image called sparse image blocks to be bound to specific ranges of memory. This allows the application to manage residency at either image subresource or sparse image block granularity. Each image subresource (outside of the mip tail) starts on a sparse block boundary and has dimensions that are integer multiples of the corresponding dimensions of the sparse image block.

Note

Applications can use these types of im= ages to control LOD based on total memory consumption. If memory pressure becomes an issue the application can unbind and disable specific mipmap levels of images without having to recreate resources or modify texel data of unaffected levels.

The application can also use this func= tionality to access subregions of the image in a =E2=80=9Cmegatexture=E2=80=9D fashion. The application can create a large image = and only populate the region of the image that is currently being used in the scene.

29.4.1. Accessing Unbound Regions=

The following member of VkPhysicalDeviceSparseProperties af= fects how data in unbound regions of sparse resources are handled by the implementation:

  • residencyNonResidentStrict

If this property is not present, reads of unbound regions of the image w= ill return undefined values. Both reads and writes are still considered safe and will not affec= t other resources or populated regions of the image.

If this property is present, all reads of unbound regions of the image w= ill behave as if the region was bound to memory populated with all zeros; write= s will be discarded.

Formatted accesses to unbound memory may still alter some component values in the natural way for those accesses, e.g. substituting a value of one for alpha in formats that do not have an alpha component.

Example: Reading the alpha component of an unbacked VK_FORMAT_R8_U= NORM image will return a value of 1.0f.

See Physical Device Enumeration for instructions for retrieving physical device properties.=

Implementor=E2=80=99s Note

For implementations that cannot native= ly handle access to unbound regions of a resource, the implementation may all= ocate and bind memory to the unbound regions. Reads and writes to unbound regions will access the implementation-managed memory instead.

Given that reads of unbound regions are undefined in this scenario, implementations may use the same physical= memory for all unbound regions of multiple resources within the same process.

29.4.2. Mip Tail Regions

Sparse images created using VK_IMAGE_CREATE_SPARSE_BINDING_BIT (without also using VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) have= no specific mapping of image region or image subresource to memory offset defined, so the entire image can be thoug= ht of as a linear opaque address region. However, images created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT do have a prescribed sparse image block layout, and hence each image subresource must start on a sparse block = boundary. Within each array layer, the set of mip levels that have a smaller size tha= n the sparse block size in bytes are grouped together into a mip tail region.

If the VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT flag is = present in the flags member of VkSparseImageFormatProperties= , for the image=E2=80=99s format, then any mip level which has dimension= s that are not integer multiples of the corresponding dimensions of the sparse image block= , and all subsequent mip levels, are also included in the mip tail region.

The following member of VkPhysicalDeviceSparseProperties may affect how the implementation places mip levels in the mip tail region:

  • residencyAlignedMipSize

Each mip tail region is bound to memory as an opaque region (i.e. must be bound using a VkSparseImageOpaqueMemoryB= indInfo structure) and may be of a size greater than or equal to the sparse block size in bytes. This size is guaranteed to be an integer multiple of the sparse block size in bytes.

An implementation may choose to allow = each array-layer=E2=80=99s mip tail region to be bound to memory independently or require that all array-layer=E2=80=99s = mip tail regions be treated as one. This is dictated by VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = in VkSparseImageMemoryRequirements::flags.

The following diagrams depict how VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT and VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT alter memory usage a= nd requirements.

3D"sparseimage"
Figure 28. Sparse Image

In the absence of VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT and VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT, each array layer co= ntains a mip tail region containing texel data for all mip levels smaller than the sparse image block in any dimension.

Mip levels that are as large or larger than a sparse image block in all dimensions can be bound individually. Right-edges and bottom-edges of each level are allowed to have partially used sparse blocks. Any bound partially-used-sparse-blocks must still have their full sparse block size in bytes allocated in memory.

3D"spa=
Figure 29. Sparse Image with Single Mip Tail

When VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is present a= ll array layers will share a single mip tail region.

3D"sparse=
Figure 30. Sparse Image with Aligned Mip Size
Note

The mip tail regions are presented here in 2D arrays simply for figure s= ize reasons. Each mip tail is logically a single array of sparse blocks with an implementation-dependent mapping of texels or compressed texel blocks to sparse blocks.

When VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT is present= the first mip level that would contain partially used sparse blocks begins the mip tail region. This level and all subsequent levels are placed in the mip tail. Only the first N mip levels whose dimensions are = an exact multiple of the sparse image block dimensions can be = bound and unbound on a sparse block basis.

3D"sparseimage
Figure 31. Sparse Image with Aligned Mip Size and Sing= le Mip Tail
Note

The mip tail region is presented here in a 2D array simply for figure si= ze reasons. It is logically a single array of sparse blocks with an implementation-dependent mapping of texels or compressed texel blocks to sparse blocks.

When both VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT and VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT are present the cons= traints from each of these flags are in effect.

29.4.3. Standard Sparse Image Block= Shapes

Standard sparse image block shapes define a standard set of dimensions f= or sparse image blocks that depend on the format of the image. Layout of texels or compressed texel blocks within a sparse image block is implementation dependent. All currently defined standard sparse image block shapes are 64 KB in size.=

For block-compressed formats (e.g. VK_FORMAT_BC5_UNORM_BLOCK), the texel size is the size of the compressed texel block (e.g. 128-bit for BC5) thus the dimensions of the standard sparse image block sh= apes apply in terms of compressed texel blocks.

Note

For block-compressed formats, the dimensions of a sparse image block in terms of texels can be calculated by mult= iplying the sparse image block dimensions by the compressed texel block dimensions.

Table 41. Standard Sparse Image Block Shapes (Sing= le Sample)
TEXEL SIZE (bits) Block Shape (2D) Block Shape (3D)

8-Bit

256= =C3=97 256 =C3=97 1

64 = =C3=97 32 =C3=97 32

16-Bit

256= =C3=97 128 =C3=97 1

32 = =C3=97 32 =C3=97 32

32-Bit

128= =C3=97 128 =C3=97 1

32 = =C3=97 32 =C3=97 16

64-Bit

128= =C3=97 64 =C3=97 1

32 = =C3=97 16 =C3=97 16

128-Bit

64 = =C3=97 64 =C3=97 1

16 = =C3=97 16 =C3=97 16

Table 42. Standard Sparse Image Block Shapes (MSAA= )
TEXEL SIZE (bits) Block Shape (2X) Block Shape (4X) Block Shape (8X) Block Shape (16X)

8-Bit

128= =C3=97 256 =C3=97 1

128= =C3=97 128 =C3=97 1

64 = =C3=97 128 =C3=97 1

64 = =C3=97 64 =C3=97 1

16-Bit

128= =C3=97 128 =C3=97 1

128= =C3=97 64 =C3=97 1

64 = =C3=97 64 =C3=97 1

64 = =C3=97 32 =C3=97 1

32-Bit

64 = =C3=97 128 =C3=97 1

64 = =C3=97 64 =C3=97 1

32 = =C3=97 64 =C3=97 1

32 = =C3=97 32 =C3=97 1

64-Bit

64 = =C3=97 64 =C3=97 1

64 = =C3=97 32 =C3=97 1

32 = =C3=97 32 =C3=97 1

32 = =C3=97 16 =C3=97 1

128-Bit

32 = =C3=97 64 =C3=97 1

32 = =C3=97 32 =C3=97 1

16 = =C3=97 32 =C3=97 1

16 = =C3=97 16 =C3=97 1

Implementations that support the standard sparse image block shape for a= ll formats listed in the Standard Sparse= Image Block Shapes (Single Sample) and Standard Sparse Image Block Shapes (MSA= A) tables may advertise the following VkPhysicalDeviceSparseProperties:

  • residencyStandard2DBlockShape

  • residencyStandard2DMultisampleBlockShape

  • residencyStandard3DBlockShape

Reporting each of these features does not imply that all possib= le image types are supported as sparse. Instead, this indicates that no supported sparse image of the corresponding type will use custom sparse image block dimensions for any formats that hav= e a corresponding standard sparse image block shape.

29.4.4. Custom Sparse Image Block Sha= pes

An implementation that does not support a standard image block shape for= a particular sparse partially-resident image may choose to support a custom sparse image block shape for it instead. The dimensions of such a custom sparse image block shape are reported in VkSparseImageFormatProperties::imageGranularity. As with standard sparse image block shapes, the size in bytes of the custom sparse image block shape will be reported in VkMemoryRequirements::alignment.

Custom sparse image block dimensions are reported through vkGetPhysicalDeviceSparseImageFormatProperties and vkGetImageSparseMemoryRequirements.

An implementation must not support bot= h the standard sparse image block shape and a custom sparse image block shape for the same image. The standard sparse image block shape must be used if it is supported.

29.4.5. Multiple Aspects

Partially resident images are allowed to report separate sparse properti= es for different aspects of the image. One example is for depth/stencil images where the implementation separates the depth and stencil data into separate planes. Another reason for multiple aspects is to allow the application to manage memory allocation for implementation-private metadata associated w= ith the image. See the figure below:

3D"sparseimage
Figure 32. Multiple Aspect Sparse Image
Note

The mip tail regions are presented here in 2D arrays simply for figure s= ize reasons. Each mip tail is logically a single array of sparse blocks with an implementation-dependent mapping of texels or compressed texel blocks to sparse blocks.

In the figure above the depth, stencil, and metadata aspects all have un= ique sparse properties. The per-texel stencil data is =C2=BC the size of = the depth data, hence the stencil sparse blocks include 4 =C3=97 = the number of texels. The sparse block size in bytes for all of the aspects is identical and defined by VkMemoryRequirements::alignment.

Metadata

The metadata aspect of an image has the following constraints:

  • All metadata is reported in the mip tail region of the metadata aspect.<= /p>

  • All metadata must be bound prior to de= vice use of the sparse image.

29.5. Sparse Memory Aliasing=

By default sparse resources have the same aliasing rules as non-sparse resources. See Memory Aliasing for more information.

VkDevice objects that have the sparseResidencyAliased featur= e enabled are able to use the VK_BUFFER_CREATE_SPARSE_ALIASED_BIT and VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flags for resource creation= . These flags allow resources to access physical memory bound into multiple locations within one or more sparse resources in a data consistent fashion. This means that reading physical memory from multiple aliased locations wil= l return the same value.

Care must be taken when performing a w= rite operation to aliased physical memory. Memory dependencies must be used to separ= ate writes to one alias from reads or writes to another alias. Writes to aliased memory that are not properly guarded against accesses to different aliases will have undefined results for all accesses to the aliased memory.

Applications that wish to make use of data consistent sparse memory alia= sing must abide by the following guidelines:

  • All sparse resources that are bound to aliased physical memory must be created with the VK_BUFFER_CREATE_SPARSE_ALIASED_BIT / VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flag.

  • All resources that access aliased physical memory must interpret the memory in the same way. This implies the following:

    • Buffers and images cannot alias the sa= me physical memory in a data consistent fashion. The physical memory ranges must be used e= xclusively by buffers or used exclusively by images for data consistency to be guaranteed.

    • Memory in sparse image mip tail regions cannot<= /strong> access aliased memory in a data consistent fashion.

    • Sparse images that alias the same physical memory must have compatible formats and be using the same sparse image block shape in order to access aliased memory in a data consistent fashion.

Failure to follow any of the above guidelines will require the applicati= on to abide by the normal, non-sparse resource alia= sing rules. In this case memory cannot be accessed in= a data consistent fashion.

Note

Enabling sparse resource memory aliasing can be a way to lower physical memory use, but it may reduce performance= on some implementations. An application developer can test on thei= r target HW and balance the memory / performance trade-offs measured.

29.6. Sparse Resource= Implementation Guidelines

This section is Informative. It is included to aid in implementors=E2=80=99 understanding of sparse reso= urces.

Device Virtual Address

The basic sparseBinding feature allows the resource to rese= rve its own device virtual address range at resource creation time rather than relying on a bind operation to set this. Without any other creation flags, no other constraints are relaxed compared to normal resources. All pages must be bound to physical memor= y before the device accesses the resource.

The sparse residency features all= ow sparse resources to be used even when not all pages are bound to memory. Implementations that support access to unbound pages without causing a faul= t may support residencyNonResidentStr= ict.

Not faulting on access to unbound pages is not enough to support residencyNonResidentStrict. An implementation must also guarantee tha= t reads after writes to unbound regions of the resource always return data for the read as if the memory contains zeros. Depending on any caching hierarchy of the implementation this may not always be possible.

Any implementation that does not fault, but does not guarantee correct r= ead values must not support residencyNo= nResidentStrict.

Any implementation that cannot access = unbound pages without causing a fault will require the implementation to bind the entire device virtual address range to physical memory. Any pages that the application does not bind to memory may be bound to one (or more) =E2=80=9Cdummy=E2=80=9D physical page(s) allocated by the impleme= ntation. Given the following properties:

  • A process must not access memory from = another process

  • Reads return undefined values

It is sufficient for each host process to allocate these dummy pages and= use them for all resources in that process. Implementations may allocate more often (= per instance, per device, or per resource).

Binding Memory

The byte size reported in VkMemoryRequirements::size<= /code> must be greater than or equal to the amount of physical memory required to fully populate the resource. Some implementations require =E2=80=9Choles=E2=80=9D in the device virtual = address range that are never accessed. These holes may be included in the = size reported for the resource.

Including or not including the device virtual address holes in the resou= rce size will alter how the implementation provides support for VkSparseImageOpaqueMemoryBindInfo. This operation must be supported for all = sparse images, even ones created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

editing-note

@ntrevett suggested expanding the NOTE tag below to encompass everything from =E2=80=9CThe cost is=E2=80=A6=E2=80=8B=E2=80=9D in the first bullet po= int through the current note. TBD.

  • If the holes are included in the size, this bind function becomes very easy. In most cases the resourceOffset is simply a device virtual address offset and the implementation can easily determine what device virtual address to bind. The cost is that the application may allo= cate more physical memory for the resource than it needs.

  • If the holes are not included in the size, the application can allocate less physical memory than otherwise for the resource. However, in this case the implementation must account for the holes when mapping resourceOffset to the actual device virtual addre= ss intended to be mapped.

Note

If the application always uses VkSparseImageMemoryBindInfo = to bind memory for the non-tail mip levels, any holes that are present in the resource size may never be bound.

Since VkSparseImageMemoryBindInfo uses texel locations to d= etermine which device virtual addresses to bind, it is impossible to bind device virtual address holes with this operation.

Binding Metadata Memory

All metadata for sparse images have their own sparse properties and are embedded in the mip tail region for said properties. See the Multiaspect section for details.

Given that metadata is in a mip tail region, and the mip tail region must be reported as contiguous (either globally or per-array-layer), some implementations will have to resort to complicated offset =E2=86=92 device = virtual address mapping for handling VkSparseImageOpaqueMemoryBindInfo= .

To make this easier on the implementation, the VK_SPARSE_MEMORY_BIND_METADATA_BIT explicitly specifies when m= etadata is bound with VkSparseImageOpaqueMemoryBindInfo. When this flag is not present, the resourceOffset may be treated as a strict device virtual address offset.

When VK_SPARSE_MEMORY_BIND_METADATA_BIT is present, the resourceOffset must have bee= n derived explicitly from the imageMipTailOffset in the sparse resource properties returned = for the metadata aspect. By manipulating the value returned for imageMipTailOffset, the resourceOffset does not have to correlate directly to a device= virtual address offset, and may instead be whatev= er values makes it easiest for the implementation to derive the correct device virtual address.

29.7. Sparse Resource API

The APIs related to sparse resources are grouped into the following categories:

29.7.1. Physical Device Features

Some sparse-resource related features are reported and enabled in VkPhysicalDeviceFeatures. These features must be supported and enab= led on the VkDevice object before applications can use them. See Physical Device Features for information on how = to get and set enabled device features, and for more detailed explanations of these features.

Sparse Physical Device Features=
  • sparseBinding: Support for creating VkBuffer = and VkImage objects with the VK_BUFFER_CREATE_SPARSE_BINDING= _BIT and VK_IMAGE_CREATE_SPARSE_BINDING_BIT flags, respectively.

  • sparseResidencyBuffer: Support for creating VkBuf= fer objects with the VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT flag.

  • sparseResidencyImage2D: Support for creating 2D single-samp= led VkImage objects with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BI= T.

  • sparseResidencyImage3D: Support for creating 3D Vk= Image objects with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

  • sparseResidency2Samples: Support for creating 2D V= kImage objects with 2 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

  • sparseResidency4Samples: Support for creating 2D V= kImage objects with 4 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

  • sparseResidency8Samples: Support for creating 2D V= kImage objects with 8 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

  • sparseResidency16Samples: Support for creating 2D VkImage objects with 16 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT.

  • sparseResidencyAliased: Support for creating VkBu= ffer and VkImage objects with the VK_BUFFER_CREATE_SPARSE_ALIASED= _BIT and VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flags, respectively.

29.7.2. Physical Device Sparse Proper= ties

Some features of the implementation are not possible to disable, and are reported to allow applications to alter their sparse resource usage accordingly. These read-only capabilities are reported in the VkPhysicalDeviceProperties::sparsePro= perties member, which is a structure of type VkPhysicalDeviceSparseProperties.

The VkPhysicalDeviceSparseProperties structure is defined a= s:

typedef struct VkPhysicalDevice=
SparseProperties {
    VkBool32    residencyStandard2DBlockShape;
    VkBool32    residencyStandard2DMultisampleBlockShape;
    VkBool32    residencyStandard3DBlockShape;
    VkBool32    residencyAlignedMipSize;
    VkBool32    residencyNonResidentStrict;
} VkPhysicalDeviceSparseProperties;
  • residencyStandard2DBlockShape is VK_TRUE if th= e physical device will access all single-sample 2D sparse resources using the standard sparse image block shapes (based on image format), as described in the Standard Sparse Image Block Shapes (Single Sample) table. If this property is not supported the value returned in the imageGranularity member of the VkSparseImageFormatProper= ties structure for single-sample 2D images is not requi= red to match the standard sparse image block dimensions listed in the table.

  • residencyStandard2DMultisampleBlockShape is VK_TRUE if the physical device will access all multisample 2D sparse resources using the standard sparse image block shapes (based on image format), as described in the Standard Sparse Image Block Shapes (MSAA) table. If this property is not supported, the value returned in the imageGranularity member of the VkSparseImageFormatProper= ties structure for multisample 2D images is not require= d to match the standard sparse image block dimensions listed in the table.

  • residencyStandard3DBlockShape is VK_TRUE if th= e physical device will access all 3D sparse resources using the standard sparse image block shapes (based on image format), as described in the Standard Sparse Image Block Shapes (Single Sample) table. If this property is not supported, the value returned in the imageGranularity member of the VkSparseImageFormatProper= ties structure for 3D images is not required t= o match the standard sparse image block dimensions listed in the table.

  • residencyAlignedMipSize is VK_TRUE if images w= ith mip level dimensions that are not integer multiples of the corresponding dimensions of the sparse image block may = be placed in the mip tail. If this property is not reported, only mip levels with dimensions smaller than the imageGranularity member of the VkSparseImageFormatProperties structure will be placed in the = mip tail. If this property is reported the implementation is allowed to return VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT in the flags= member of VkSparseImageFormatProperties, indicating that mip l= evel dimensions that are not integer multiples of the corresponding dimensions of the sparse image block will be placed in the mip tail.

  • residencyNonResidentStrict specifies whether the physical d= evice can consistently access non-resident regi= ons of a resource. If this property is VK_TRUE, access to non-resident regions of resources will be guaranteed to return values as if the resource were populated with 0; writes to non-resident regions will be discarded.

29.7.3. Sparse Image Format Properties=

Given that certain aspects of sparse image support, including the sparse image block dimensions, may be implementa= tion-dependent, vkGetPhysicalDeviceSparseIm= ageFormatProperties can be used to qu= ery for sparse image format properties prior to resource creation. This command is used to check whether a given set of sparse image parameter= s is supported and what the sparse image block shape will be.

Sparse Image Format Properti= es API

The VkSparseImageFormatProperties structure is defined as:<= /p>

typedef struct VkSparseImageFor=
matProperties {
    VkImageAspectFlags          aspectMask;
    VkExtent3D                  imageGranularity;
    VkSparseImageFormatFlags    flags;
} VkSparseImageFormatProperties;
  • aspectMask is a bitmask VkImageAspec= tFlagBits specifying which aspects of the image the properties apply to.

  • imageGranularity is the width, height, and depth of the spa= rse image block in texels or compressed texel blocks.

  • flags is a bitmask of VkSparse= ImageFormatFlagBits specifying additional information about the sparse resource.

Bits which can be set in VkSparseImageFormatProperties::flags, specifying additional information about the sparse resource, are:

typedef enum VkSparseImageForma=
tFlagBits {
    VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT =3D 0x000=
00001,
    VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT =3D 0x0=
0000002,
    VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT =3D 0x00000004,
} VkSparseImageFormatFlagBits;
  • VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT specifies that th= e image uses a single mip tail region for all array layers.

  • VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT specifies that = the first mip level whose dimensions are not integer multiples of the corresponding dimensions of the sparse image block begins the mip tail region.

  • VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT specifies= that the image uses non-standard sparse image block dimensions, and the imageGranularity values do not match the standard sparse image block dimensions for the given format.

typedef VkFlags VkSparseImageFormatFlags;

VkSparseImageFormatFlags is a bitmask type for setting a ma= sk of zero or more VkSparseImageFormatFlagBits.

vkGetPhysicalDeviceSparseImageFormatProperties returns an a= rray of VkSparseImageFormatProperties. Each element will describe properties for one set of image aspects that are bound simultaneously in the image. This is usually one element for each aspect in the image, but for interleaved depth/stencil images there is only one element describing the combined aspects.

void vkGetPhysicalDeviceSparseImageFormatProperties(
    VkPhysicalDevice                            physicalDevice,
    VkFormat                                    format,
    VkImageType                                 type,
    VkSampleCountFlagBits                       samples,
    VkImageUsageFlags                           usage,
    VkImageTiling                               tiling,
    uint32_t*                                   pPropertyCount,
    VkSparseImageFormatProperties*              pProperties);
  • physicalDevice is the physical device from which to query t= he sparse image capabilities.

  • format is the image format.

  • type is the dimensionality of image.

  • samples is the number of samples per texel as defined in VkSampleCountFlagBits.

  • usage is a bitmask describing the intended usage of the ima= ge.

  • tiling is the tiling arrangement of the data elements in me= mory.

  • pPropertyCount is a pointer to an integer related to the nu= mber of sparse format properties available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkSparseImageFormatProperties structures= .

If pProperties is NULL, then the number of spa= rse format properties available is returned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return= the variable is overwritten with the number of structures actually written to pProperties. If pPropertyCount is less than the number of sparse format pro= perties available, at most pPropertyCount structures will be written.<= /p>

If VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT is not supported fo= r the given arguments, pPropertyCount will be set to zero upon return, and= no data will be written to pProperties.

Multiple aspects are returned for depth/stencil images that are implemen= ted as separate planes by the implementation. The depth and stencil data planes each have unique VkSparseImageFormatProperties data.

Depth/stencil images with depth and stencil data interleaved into a sing= le plane will return a single VkSparseImageFormatProperties struc= ture with the aspectMask set to VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT.

Valid Usage
  • samples must be a bit value = that is set in VkImageFormatProperties::sampleCounts returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, and usage equal to tho= se in this command and flags equal to the value that is set in VkImageCreateInfo::flags when the image is create= d

Valid Usage (Implicit)
  • physicalDevice mu= st be a valid VkPhysicalDevice handle

  • format must be a= valid VkFormat value

  • type must be a val= id VkImageType value

  • samples must be= a valid VkSampleCountFlagBits value

  • usage must be a v= alid combination of VkImageUsageFlagBits values

  • usage must = not be 0

  • tiling must be a= valid VkImageTiling value

  • pPropertyCount mu= st be a valid pointer to a uint32_t value

  • If the value referenced by pPropertyCount is = not 0, and pProperties is not NULL, = pProperties must be a valid = pointer to an array of pPropertyCount VkSparseImageForma= tProperties structures

vkGetPhysicalDeviceSparseImageFormatProperties2 returns an = array of VkSparseImageFormatProperties2. Each element will describe properties for one set of image aspects that are bound simultaneously in the image. This is usually one element for each aspect in the image, but for interleaved depth/stencil images there is only one element describing the combined aspects.

void vkGetPhysicalDeviceSparseImageFormatProperties2(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceSparseImageForma=
tInfo2* pFormatInfo,
    uint32_t*                                   pPropertyCount,
    VkSparseImageFormatProperties2*             pProperties);

or the equivalent command

void vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceSparseImageForma=
tInfo2* pFormatInfo,
    uint32_t*                                   pPropertyCount,
    VkSparseImageFormatProperties2*             pProperties);
  • physicalDevice is the physical device from which to query t= he sparse image capabilities.

  • pFormatInfo is a pointer to a structure of type VkPhysicalDeviceSparseImageFormatIn= fo2 containing input parameters to the command.

  • pPropertyCount is a pointer to an integer related to the nu= mber of sparse format properties available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkSparseImageFormatProperties2 structur= es.

vkGetPhysicalDeviceSparseImageFormatProperties2 behaves ide= ntically to vkGetPhysicalDeviceSparseIm= ageFormatProperties, with the ability to return extended information by adding extension structures to the pNext chain of its pProperties parameter.

Valid Usage (Implicit)
  • physicalDevice m= ust be a valid VkPhysicalDevice handle

  • pFormatInfo must be a valid pointer to a valid VkPhysicalDeviceSparseImageForma= tInfo2 structure

  • pPropertyCount m= ust be a valid pointer to a uint32_t value

  • If the value referenced by pPropertyCount is= not 0, and pProperties is not NULL,= pProperties must be a valid= pointer to an array of pPropertyCount VkSparseImageForm= atProperties2 structures

The VkPhysicalDeviceSparseImageFormatInfo2 structure is def= ined as:

typedef struct VkPhysicalDevice=
SparseImageFormatInfo2 {
    VkStructureType          sType;
    const void*              pNext;
    VkFormat                 format;
    VkImageType              type;
    VkSampleCountFlagBits    samples;
    VkImageUsageFlags        usage;
    VkImageTiling            tiling;
} VkPhysicalDeviceSparseImageFormatInfo2;

or the equivalent

typedef VkPhysicalDeviceSparseImageFormatInfo2 VkPhysicalDevic=
eSparseImageFormatInfo2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • format is the image format.

  • type is the dimensionality of image.

  • samples is the number of samples per texel as defined in VkSampleCountFlagBits.

  • usage is a bitmask describing the intended usage of the ima= ge.

  • tiling is the tiling arrangement of the data elements in me= mory.

Valid Usage
  • samples must be a bit value = that is set in VkImageFormatProperties::sampleCounts returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, and usage equal to tho= se in this command and flags equal to the value that is set in VkImageCreateInfo::flags when the image is create= d

The VkSparseImageFormatProperties2 structure is defined as:=

typedef struct VkSparseImageFor=
matProperties2 {
    VkStructureType                  sType;
    void*                            pNext=
;
    VkSparseImageFormatProperties    properties;
} VkSparseImageFormatProperties2;

or the equivalent

typedef VkSparseImageFormatProperties2 VkSparseImageFormatProp=
erties2KHR;
Valid Usage (Implicit)
  • sTy= pe must be VK_STRUCTURE_TYPE= _SPARSE_IMAGE_FORMAT_PROPERTIES_2

  • pNe= xt must be NULL

29.7.4. Sparse Resource Creation<= /h4>

Sparse resources require that one or more sparse feature flags be specif= ied (as part of the VkPhysicalDeviceFeatures structure described previously in the Physical Device Features section) at CreateDevice time. When the appropriate device features are enabled, the VK_BUFFER_CREATE_SPARSE_* and VK_IMAGE_CREATE_SPARSE_* flags can be used. See vkCreateBuffer and vkCreateImage= for details of the resource creation APIs.

Note

Specifying VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT requires specifying VK_BUFFER_CREATE_SPARSE_BINDING_BIT or VK_IMAGE_CREATE_SPARSE_BINDING_BIT, respectively, as well. This means that resources must be created= with the appropriate *_SPARSE_BINDING_BIT to be used with the sparse binding comman= d (vkQueueBindSparse).

29.7.5. Sparse Resource Memory = Requirements

Sparse resources have specific memory requirements related to binding sp= arse memory. These memory requirements are reported differently for VkBuffer objects and VkImage objects.

Buffer and Fully-Resid= ent Images

Buffers (both fully and partially resident) and fully-resident images can be bound to memory using only the data from VkMemoryRequirements. For all sparse resources the VkMemoryRequirements::align= ment member specifies both the bindable sparse block size in bytes and required alignment of VkDeviceMemory.

Partially Resident Images=

Partially resident images have a different method for binding memory. As with buffers and fully resident images, the VkMemoryRequirements::alignment field specifies t= he bindable sparse block size in bytes for the image.

Requesting sparse memory requirements for VkImage objects u= sing vkGetImageSparseMemoryRequirements will return an array of one= or more VkSparseImageMemoryRequirements structures. Each structure describes the sparse memory requirements for a group of aspects of the image.

The sparse image must have been create= d using the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT flag to retrieve valid sp= arse image memory requirements.

Sparse Image Memory Requiremen= ts

The VkSparseImageMemoryRequirements structure is defined as= :

typedef struct VkSparseImageMem=
oryRequirements {
    VkSparseImageFormatProperties    formatProperties;
    uint32_t                         imageMipTailFirstLod;
    VkDeviceSize                     imageMipTailSize;
    VkDeviceSize                     imageMipTailOffset;
    VkDeviceSize                     imageMipTailStride;
} VkSparseImageMemoryRequirements;
  • formatProperties.aspectMask is the set of aspects of the im= age that this sparse memory requirement applies to. This will usually have a single aspect specified. However, depth/stencil images may have de= pth and stencil data interleaved in the same sparse block, in which case both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BI= T would be present.

  • formatProperties.imageGranularity describes the dimensions = of a single bindable sparse image block in texel units. For aspect VK_IMAGE_ASPECT_METADATA_BIT, all dimensions will b= e zero. All metadata is located in the mip tail region.

  • formatProperties.flags is a bitmask of VkSparseImageFormatFlagBits:

    • If VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is set the ima= ge uses a single mip tail region for all array layers.

    • If VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT is set the dimensions of mip levels must be integer = multiples of the corresponding dimensions of the sparse image block for levels not located in the mip tail.

    • If VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT is set= the image uses non-standard sparse image block dimensions. The formatProperties.imageGranularity values do not match the standard sparse image block dimension corresponding to the image=E2=80=99s format.

  • imageMipTailFirstLod is the first mip level at which image subresources are included in the mip tail region.

  • imageMipTailSize is the memory size (in bytes) of the mip t= ail region. If formatProperties.flags contains VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT, this is the size of= the whole mip tail, otherwise this is the size of the mip tail of a single array layer. This value is guaranteed to be a multiple of the sparse block size in bytes.

  • imageMipTailOffset is the opaque memory offset used with VkSparseImageOpaqueMemoryBindInfo to= bind the mip tail region(s).

  • imageMipTailStride is the offset stride between each array-= layer=E2=80=99s mip tail, if formatProperties.flags does not contain VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT (otherwise the value= is undefined).

To query sparse memory requirements for an image, call:

void vkGetImageSparseMemoryRequirements(
    VkDevice                                    device,
    VkImage                                     image,
    uint32_t*                                   pSparseMemoryRequirementCou=
nt,
    VkSparseImageMemoryRequirements*            pSparseMemoryRequirements);=
  • device is the logical device that owns the image.

  • image is the VkImage object to get the memory = requirements for.

  • pSparseMemoryRequirementCount is a pointer to an integer re= lated to the number of sparse memory requirements available or queried, as described below.

  • pSparseMemoryRequirements is either NULL or a = pointer to an array of VkSparseImageMemoryRequirements structures.

If pSparseMemoryRequirements is NULL, then the= number of sparse memory requirements available is returned in pSparseMemoryRequirementCount. Otherwise, pSparseMemoryRequirementCount must point to a variable set by the user to the number of elements in the pSparseMemoryRequirement= s array, and on return the variable is overwritten with the number of structures actually written to pSparseMemoryRequirements. If pSparseMemoryRequirementCount is less than the number of sp= arse memory requirements available, at most pSparseMemoryRequirementCount<= /code> structures will be written.

If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY= _BIT then pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to.

Note

It is legal for an implementation to report a larger value in VkMemoryRequirements::size than would be obtained= by adding together memory sizes for all VkSparseImageMemoryRequirements = returned by vkGetImageSparseMemoryRequirements. This may occur when the implementation re= quires unused padding in the address range describing the resource.

Valid Usage (Implicit)
  • = device must be a valid VkDevice handle

  • <= code>image must be a valid V= kImage handle

  • pSparseMemoryRequirementCount must be a valid pointer to a uint32_t= value

  • If the value referenced by pSparseMemoryRequiremen= tCount is not 0, and pSparseMemoryRequirements is not NULL, pSparseMemoryRequirements must be a valid pointer to an array of p= SparseMemoryRequirementCount VkSparseImageMemoryRequirements structures

  • image must have been created, al= located, or retrieved from device

To query sparse memory requirements for an image, call:

void vkGetImageSparseMemoryRequirements2(
    VkDevice                                    device,
    const VkImageSparseMemoryRequirementsI=
nfo2* pInfo,
    uint32_t*                                   pSparseMemoryRequirementCou=
nt,
    VkSparseImageMemoryRequirements2*           pSparseMemoryRequirements);=

or the equivalent command

void vkGetImageSparseMemoryRequirements2KHR(
    VkDevice                                    device,
    const VkImageSparseMemoryRequirementsI=
nfo2* pInfo,
    uint32_t*                                   pSparseMemoryRequirementCou=
nt,
    VkSparseImageMemoryRequirements2*           pSparseMemoryRequirements);=
  • device is the logical device that owns the image.

  • pInfo is a pointer to an instance of the VkImageSparseMemoryRequirementsInfo2 structure containing parameters required for the memory requirements query.

  • pSparseMemoryRequirementCount is a pointer to an integer re= lated to the number of sparse memory requirements available or queried, as described below.

  • pSparseMemoryRequirements is either NULL or a = pointer to an array of VkSparseImageMemoryRequirements2 structures.

Valid Usage (Implicit)
  • = device must be a valid VkDevice handle

  • = pInfo must be a valid pointe= r to a valid VkImageSparseMemoryRequirementsInfo2 structure

  • pSparseMemoryRequirementCount must be a valid pointer to a uint32_t value

  • If the value referenced by pSparseMemoryRequireme= ntCount is not 0, and pSparseMemoryRequirements is not NULL, pSparseMemoryRequirements must be a valid pointer to an array of = pSparseMemoryRequirementCount VkSparseImageMemoryRequirements2= structures

The VkImageSparseMemoryRequirementsInfo2 structure is defin= ed as:

typedef struct VkImageSparseMem=
oryRequirementsInfo2 {
    VkStructureType    sType;
    const void*        pNext;
    VkImage            image;
} VkImageSparseMemoryRequirementsInfo2;

or the equivalent

typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemo=
ryRequirementsInfo2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • image is the image to query.

Valid Usage (Implicit)
  • sType must be VK_STRUCTUR= E_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2

  • pNext must be NULL=

  • = image must be a valid VkImage handle

The VkSparseImageMemoryRequirements2 structure is defined a= s:

typedef struct VkSparseImageMem=
oryRequirements2 {
    VkStructureType                    sType;
    void*                              pNe=
xt;
    VkSparseImageMemoryRequirements    memoryRequirements;
} VkSparseImageMemoryRequirements2;

or the equivalent

typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRe=
quirements2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • memoryRequirements is a structure of type VkSparseImageMemoryRequirements descri= bing the memory requirements of the sparse image.

Valid Usage (Implicit)
  • s= Type must be VK_STRUCTURE_TY= PE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2

  • p= Next must be NULL

29.7.6. Binding Resource Memory

Non-sparse resources are backed by a single physical allocation prior to device use (via vkBindImageMemory or vkBindBufferMemory<= /code>), and their backing must not be changed. On the other hand, sparse resources can b= e bound to memory non-contiguously and these bindings can be altered during = the lifetime of the resource.

Note

It is important to note that freeing a VkDeviceMemory objec= t with vkFreeMemory will not cause resources (or resource regions) bo= und to the memory object to become unbound. Access to resources that are bound to memory objects that have been freed will result in undefined behavior, potentially including application termination.

Implementations must ensure that no ac= cess to physical memory owned by the system or another process will occur in this scenario. In other words, accessing resources bound to freed memory may result in application termination, but must not res= ult in system termination or in reading non-process-accessible memory.

Sparse memory bindings execute on a queue that includes the VK_QUEUE_SPARSE_BINDING_BIT bit. Applications must use sy= nchronization primitives to guarantee that other queues do not access ranges of memory concurrently wit= h a binding change. Accessing memory in a range while it is being rebound results in undefined behavior. It is valid to access other ranges of the same resource while a bind operation is executing.

Note

Implementations must provide a guarant= ee that simultaneously binding sparse blocks while another queue accesses those same sparse blocks via a sparse resource must not access memory owned by = another process or otherwise corrupt the system.

While some implementations may include= VK_QUEUE_SPARSE_BINDING_BIT support in queue families that also include graphics and compute support, other implementations may only expose a VK_QUEUE_SPARSE_BINDING_BIT-only queue family. In either case, applications must use synchronization primitives to explicitly request any ordering dependencies between spar= se memory binding operations and other graphics/compute/transfer operations, a= s sparse binding operations are not automatically ordered against command buffer execution, even within a single queue.

When binding memory explicitly for the VK_IMAGE_ASPECT_METADATA_BI= T the application must use the VK_SPA= RSE_MEMORY_BIND_METADATA_BIT in the VkSparseMemoryBind::flags field when binding = memory. Binding memory for metadata is done the same way as binding memory for the mip tail, with the addition of the VK_SPARSE_MEMORY_BIND_METADATA_BIT= flag.

Binding the mip tail for any aspect must only be performed using VkSparseImageOpaqueMemoryBindInfo. If formatProperties.flags contains VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT, then it can be bound with a single VkSparseMemoryBind structure, with r= esourceOffset =3D imageMipTailOffset and size =3D imageMipTai= lSize.

If formatProperties.flags does not contain VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT then the offset for = the mip tail in each array layer is given as:

arrayMipTailOffset=
 =3D imageMipTailOffset + arrayLayer * imageMipTailStride;

and the mip tail can be bound with layerCount VkSparseMemoryBind structures, each using size =3D imageMipTailSize = and resourceOffset =3D arrayMipTailOffset as defined = above.

Sparse memory binding is handled by the following APIs and related data structures.

Sparse Memory Binding Functions

The VkSparseMemoryBind structure is defined as:

typedef struct VkSparseMemoryBi=
nd {
    VkDeviceSize               resourceOffset;
    VkDeviceSize               size;
    VkDeviceMemory             memory;
    VkDeviceSize               memoryOffset;
    VkSparseMemoryBindFlags    flags;
} VkSparseMemoryBind;
  • resourceOffset is the offset into the resource.

  • size is the size of the memory region to be bound.

  • memory is the VkDeviceMemory object tha= t the range of the resource is bound to. If memory is VK_NULL_HANDLE, the range is = unbound.

  • memoryOffset is the offset into the VkDevic= eMemory object to bind the resource range to. If memory is VK_NULL_HANDLE, this value is= ignored.

  • flags is a bitmask of VkSparseM= emoryBindFlagBits specifying usage of the binding operation.

The binding range [resourceOffset, resourceOffset +=20 size) has different constraints based on flags. If flags contains VK_SPARSE_MEMORY_BIND_METADATA_BIT, the binding range must be within the mip tail= region of the metadata aspect. This metadata region is defined by:

metadataRegion =3D [base, base + imageMipTailS= ize)

base =3D imageMipTailOffset + ima= geMipTailStride =C3=97 n

and imageMipTailOffset, imageMipTailSize, and imageMipTailStride values are from the VkSparseImageMemoryRequirements corres= ponding to the metadata aspect of the image, and n is a valid array layer index = for the image,

imageMipTailStride is considered to be zero for aspects whe= re VkSparseImageMemoryRequirements::formatProperties.flags<= /code> contains VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT.

If flags does not contain VK_SPARSE_MEMORY_BIND_METAD= ATA_BIT, the binding range must be within the rang= e [0,VkMemoryRequirements::size).

Valid Usage
  • If memory is not VK_NULL_HANDLE, mem= ory and memoryOffset must match the = memory requirements of the resource, as described in section Resource Memory Association<= /a>

  • If memory is not VK_NULL_HANDLE, mem= ory must not have been created with a memory type that reports VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set

  • size must be greater than 0

  • resourceOffset must be less = than the size of the resource

  • size must be less than or eq= ual to the size of the resource minus resourceOffset

  • memoryOffset must be less th= an the size of memory

  • size must be less than or eq= ual to the size of memory minus memoryOffset

Valid Usage (Implicit)

Bits which can be set in VkSparseMemoryBind::flags, specifying usage of a sparse memory binding operation, are:

typedef enum VkSparseMemoryBind=
FlagBits {
    VK_SPARSE_MEMORY_BIND_METADATA_BIT =3D 0x00000001,
} VkSparseMemoryBindFlagBits;
  • VK_SPARSE_MEMORY_BIND_METADATA_BIT specifies that the memor= y being bound is only for the metadata aspect.

typedef VkFlags VkSparseMemoryBindFlags;

VkSparseMemoryBindFlags is a bitmask type for setting a mas= k of zero or more VkSparseMemoryBindFlagBits.

Memory is bound to VkBuffer objects created with the VK_BUFFER_CREATE_SPARSE_BINDING_BIT flag using the following structure:

typedef struct VkSparseBufferMe=
moryBindInfo {
    VkBuffer                     buffer;
    uint32_t                     bindCount;
    const VkSparseMemoryBind*    pBinds;
} VkSparseBufferMemoryBindInfo;
Valid Usage (Implicit)
  • = buffer must be a valid VkBuf= fer handle

  • = pBinds must be a valid pointer to = an array of bindCount valid VkSparseMemoryBind st= ructures

  • <= code>bindCount must be greater tha= n 0

Memory is bound to opaque regions of VkImage objects create= d with the VK_IMAGE_CREATE_SPARSE_BINDING_BIT flag using the following st= ructure:

typedef struct VkSparseImageOpa=
queMemoryBindInfo {
    VkImage                      image;
    uint32_t                     bindCount;
    const VkSparseMemoryBind*    pBinds;
} VkSparseImageOpaqueMemoryBindInfo;
Valid Usage
  • If the flags member of any element of pBinds cont= ains VK_SPARSE_MEMORY_BIND_METADATA_BIT, the binding range defined must be within the mip tail region of the= metadata aspect of image

Valid Usage (Implicit)
Note

This operation is normally used to bind memory to fully-resident sparse images or for mip tail regions of partially resident images. However, it can also be used to bind memo= ry for the entire binding range of partially resident images.

In case flags does not contain VK_SPARSE_MEMORY_BIND_METADATA_BIT, the resourceOffset is in the range [0, VkMemoryRequirements= ::size), This range includes data from all aspects of the image, including metadata. For most implementations this will probably mean that the resourceOffset is a simple device address offset within the re= source. It is possible for an application to bind a range of memory that includes both resource data and metadata. However, the application would not know what part of the image the memory i= s used for, or if any range is being used for metadata.

When flags contains VK_SPARSE_MEMORY_BIND_METADATA_BI= T, the binding range specified must be within th= e mip tail region of the metadata aspect. In this case the resourceOffset is not required to be a simple device address offset within the resource. However, it is defined to be within [imageMipTa= ilOffset, imageMipTailOffset + imageMipTailSize) for the metadata aspect. See VkSparseMemoryBind for the full constraints on = binding region with this flag present.

editing-note

(Jon) The preceding NOTE refers to flags, which is presumab= ly a reference to VkSparseMemoryBind above, even though = that is not contextually clear.

Memory can be bound to sparse image bl= ocks of VkImage objects created with the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT flag using the f= ollowing structure:

typedef struct VkSparseImageMem=
oryBindInfo {
    VkImage                           image;
    uint32_t                          bindCount;
    const VkSparseImageMemoryBind*    pBin=
ds;
} VkSparseImageMemoryBindInfo;
Valid Usage
  • The subresource.mipLevel member of each element of pBind= s must be less than the mipLevels specified in VkImageCreateInfo when image was create= d

  • The subresource.arrayLayer member of each element of pBi= nds must be less than the arrayLayers specified in VkImageCreateInfo when image was create= d

Valid Usage (Implicit)
  • im= age must be a valid VkImage<= /code> handle

  • p= Binds must be a valid pointer to a= n array of bindCount valid VkSparseImageMemoryBind structures

  • bindCount must be greater than= 0

The VkSparseImageMemoryBind structure is defined as:

typedef struct VkSparseImageMem=
oryBind {
    VkImageSubresource         subresource;
    VkOffset3D                 offset;
    VkExtent3D                 extent;
    VkDeviceMemory             memory;
    VkDeviceSize               memoryOffset;
    VkSparseMemoryBindFlags    flags;
} VkSparseImageMemoryBind;
  • subresource is the aspectMask and region of interest in the= image.

  • offset are the coordinates of the first texel within the im= age subresource to bind.

  • extent is the size in texels of the region within the image subresource to bind. The extent must be a multiple of the spar= se image block dimensions, except when binding sparse image blocks along the edge of an image subresource it can instead be such that a= ny coordinate of offset + extent equals= the corresponding dimensions of the image subresource.

  • memory is the VkDeviceMemory object tha= t the sparse image blocks of the image are bound to. If memory is VK_NULL_HANDLE, the sparse im= age blocks are unbound.

  • memoryOffset is an offset into VkDeviceMemo= ry object. If memory is VK_NULL_HANDLE, this value is= ignored.

  • flags are sparse memory binding flags.

Valid Usage
  • If the sparse aliased residency feature is not enabled, and if any other resources are bound to ranges of memory, the range of memory being bo= und must not overlap with those bound ranges

  • memory and memoryOffset = must match the memory requirements of the calling command=E2=80=99s image, as described in sectio= n Resource Memory Association

  • subresource must be a valid = image subresource for image (see Image Views)

  • offset.x must be a multiple = of the sparse image block width (VkSparseImageFormatProperties::imageGranularity.width) of the image

  • extent.width must either be = a multiple of the sparse image block width of the image, or else (extent.width += =20 offset.x) must equal = the width of the image subresource

  • offset.y must be a multiple = of the sparse image block height (VkSparseImageFormatProperties::imageGranularity.height<= /code>) of the image

  • extent.height must either be= a multiple of the sparse image block height of the image, or else (extent.height= +=20 offset.y) must equal = the height of the image subresource

  • offset.z must be a multiple = of the sparse image block depth (VkSparseImageFormatProperties::imageGranularity.depth) of the image

  • extent.depth must either be = a multiple of the sparse image block depth of the image, or else (extent.depth += =20 offset.z) must equal = the depth of the image subresource

Valid Usage (Implicit)
  • = subresource must be a valid = VkImageSubresource structure

  • If me= mory is not VK_NULL_HANDLE, memory = must be a valid VkDeviceMemory handle

  • flags<= /code> must be a valid combination of VkSparseMemoryBindFlagBits values

To submit sparse binding operations to a queue, call:

VkResult vkQueueBi=
ndSparse(
    VkQueue                                     queue,
    uint32_t                                    bindInfoCount,
    const VkBindSparseInfo*               =
      pBindInfo,
    VkFence                                     fence);
  • queue is the queue that the sparse binding operations will = be submitted to.

  • bindInfoCount is the number of elements in the pBindI= nfo array.

  • pBindInfo is an array of VkBindSparseInfo= structures, each specifying a sparse binding submission batch.

  • fence is an optional hand= le to a fence to be signaled. If fence is not VK_NULL_HANDLE, it defines= a fence signal operation.

vkQueueBindSparse is a queue subm= ission command, with each batch defined by an element of pBindInfo as an instance of the VkBindSparseInfo structure. Batches begin execution in the order they appear in pBindInfo,= but may complete out of order.

Within a batch, a given range of a resource mus= t not be bound more than once. Across batches, if a range is to be bound to one allocation and offset and then to another allocation and offset, then the application must guarantee (usually using semaphores) that the binding operations are executed in the correct order, as well as to order binding operations against the execution of command buffer submissions.

As no operation to vkQueueBindSparse causes any p= ipeline stage to access memory, synchronization primitives used in this command effectively only define execution dependencies.

Additional information about fence and semaphore operation is described = in the synchronization chapter.

Valid Usage
  • If fence is not VK_NULL_HANDLE, fenc= e must be unsignaled

  • If fence is not VK_NULL_HANDLE, fenc= e must not be associated with any other queue command that has not yet completed execution on that queue

  • Each element of the pSignalSemaphores member of each element o= f pBindInfo must be unsignaled= when the semaphore signal operation it defines is executed on the device

  • When a semaphore unsignal operation defined by any element of the pWaitSemaphores member of any element of pBindInfo executes on queue, no other queue must be waiting on the same semaphore.

  • All elements of the pWaitSemaphores member of all elements of pBindInfo must be semaphores= that are signaled, or have semaphore signal operations previously submitted for execution.

Valid Usage (Implicit)
  • queue= must be a valid VkQueue han= dle

  • If bindI= nfoCount is not 0, pBindInfo must be a valid pointer to an array of bindInfoC= ount valid VkBindSparseInfo structures

  • If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle

  • The queue <= strong class=3D"purple">must support sparse binding operations

  • Both of fence, and queue that are valid handles must have been created, allocated, or retrieved from the same <= code>VkDevice

Host Synchronization
  • Host access to queue must= be externally synchronized

  • Host access to pBindInfo[].pWaitSemaphores[] must be externally synchronized

  • Host access to pBindInfo[].pSignalSemaphores[] must be externally synchronized

  • Host access to pBindInfo[].pBufferBinds[].buffer must be externally synchronized

  • Host access to pBindInfo[].pImageOpaqueBinds[].image must be externally synchronized

  • Host access to pBindInfo[].pImageBinds[].image must be externally synchronized

  • Host access to fence must= be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

The VkBindSparseInfo structure is defined as:

typedef struct VkBindSparseInfo=
 {
    VkStructureType                             sType;
    const void*                                 pNext;
    uint32_t                                    waitSemaphoreCount;
    const VkSemaphore*                    =
      pWaitSemaphores;
    uint32_t                                    bufferBindCount;
    const VkSparseBufferMemoryBindInfo*   =
      pBufferBinds;
    uint32_t                                    imageOpaqueBindCount;
    const VkSparseImageOpaqueMemoryBindInf=
o*    pImageOpaqueBinds;
    uint32_t                                    imageBindCount;
    const VkSparseImageMemoryBindInfo*    =
      pImageBinds;
    uint32_t                                    signalSemaphoreCount;
    const VkSemaphore*                    =
      pSignalSemaphores;
} VkBindSparseInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • waitSemaphoreCount is the number of semaphores upon which t= o wait before executing the sparse binding operations for the batch.

  • pWaitSemaphores is a pointer to an array of semaphores upon= which to wait on before the sparse binding operations for this batch begin execution. If semaphores to wait on are provided, they define a semaphore wait operation.

  • bufferBindCount is the number of sparse buffer bindings to = perform in the batch.

  • pBufferBinds is a pointer to an array of VkSparseBufferMemoryBindInfo structures.<= /p>

  • imageOpaqueBindCount is the number of opaque sparse image b= indings to perform.

  • pImageOpaqueBinds is a pointer to an array of VkSparseImageOpaqueMemoryBindInfo st= ructures, indicating opaque sparse image bindings to perform.

  • imageBindCount is the number of sparse image bindings to pe= rform.

  • pImageBinds is a pointer to an array of VkSparseImageMemoryBindInfo structures, in= dicating sparse image bindings to perform.

  • signalSemaphoreCount is the number of semaphores to be sign= aled once the sparse binding operations specified by the structure have completed execution.

  • pSignalSemaphores is a pointer to an array of semaphores wh= ich will be signaled when the sparse binding operations for this batch have completed execution. If semaphores to be signaled are provided, they define a semaphore signal operation.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_BIND_SPARSE_I= NFO

  • pNext must be NULL or a pointer to a v= alid instance of VkDeviceGroupBindSparseInfo

  • If = waitSemaphoreCount is not 0, pWaitSemaphores must be a valid pointer to an array of= waitSemaphoreCount valid VkSemaphore handles

  • If buf= ferBindCount is not 0, pBufferBinds must be a valid pointer to an array of bu= fferBindCount valid VkSparseBufferMemoryBindInfo struct= ures

  • If imageOpaqueBindCount is not 0, pImageOpaqueBind= s must be a valid pointer to an ar= ray of imageOpaqueBindCount valid VkSparseImageOpaqueMem= oryBindInfo structures

  • If imag= eBindCount is not 0, pImageBinds must be a valid pointer to an array of image= BindCount valid VkSparseImageMemoryBindInfo structures<= /p>

  • If signalSemaphoreCount is not 0, pSignalSemaphore= s must be a valid pointer to an ar= ray of signalSemaphoreCount valid VkSemaphore han= dles

  • Both of the elements o= f pSignalSemaphores, and the elements of pWaitSemaphores= that are valid handles must have = been created, allocated, or retrieved from the same VkDevice

29.8. Examples

The following examples illustrate basic creation of sparse images and binding them to physical memory.

29.8.1. Basic Sparse Resources

This basic example creates a normal VkImage object but uses fine-grained memory allocation to back the resource with multiple memory ranges.

VkDevice          =
      device;
VkQueue                 queue;
VkImage                 sparseImage;
VkAllocationCallbacks*  pAllocator =3D =
NULL;
VkMemoryRequirements    memoryRequirements =3D {};
VkDeviceSize            offset =3D 0;
VkSparseMemoryBind      binds[MAX_CHUNKS] =3D {}; /=
/ MAX_CHUNKS is NOT part of Vulkan
uint32_t                bindCount =3D 0;

// ...

// Allocate image object
const VkImageCreateInfo sparseImageInfo =
=3D
{
    VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,        // =
sType
    NULL,                       =
                // pNext
    VK_IMAGE_CREATE_SPARSE_BINDING_BIT | ...,   // =
flags
    ...
};
vkCreateImage(device, &sparseImageInfo, pAllocator, &sparseImage);

// Get memory requirements
vkGetImageMemoryRequirements(
    device,
    sparseImage,
    &memoryRequirements);

// Bind memory in fine-grained fashion, find availa=
ble memory ranges
// from potentially multiple VkDeviceMemory pools.<=
/span>
// (Illustration purposes only, can be optimized fo=
r perf)
while (memoryRequirements.size && bi=
ndCount < MAX_CHUNKS)
{
    VkSparseMemoryBind* pBind =3D &binds[bindCount];
    pBind->resourceOffset =3D offset;

    AllocateOrGetMemoryRange(
        device,
        &memoryRequirements,
        &pBind->memory,
        &pBind->memoryOffset,
        &pBind->size);

    // memory ranges must be sized as multiples of =
the alignment
    assert(IsMultiple(pBind->size, memoryRequirements.alignment));
    assert(IsMultiple(pBind->memoryOffset, memoryRequirements.alignment)=
);

    memoryRequirements.size -=3D pBind->size;
    offset                  +=3D pBind->size;
    bindCount++;
}

// Ensure all image has backing
if (memoryRequirements.size)
{
    // Error condition - too many chunks
}

const VkSparseImageOpaqueMemoryBindInfo op=
aqueBindInfo =3D
{
    sparseImage,                                // =
image
    bindCount,                                  // =
bindCount
    binds                                       // =
pBinds
};

const VkBindSparseInfo bindSparseInfo =3D
{
    VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,         // =
sType
    NULL,                       =
                // pNext
    ...
    1,                                      =
    // imageOpaqueBindCount
    &opaqueBindInfo,                            // pImageOpaqueBinds
    ...
};

// vkQueueBindSparse is externally synchronized per=
 queue object.
AcquireQueueOwnership(queue);

// Actually bind memory
vkQueueBindSparse(queue, 1, &bindSparseI=
nfo, VK_NULL_HANDLE);

ReleaseQueueOwnership(queue);

29.8.2. Advanced Sparse Resources=

This more advanced example creates an arrayed color attachment / texture image and binds only LOD zero and the required metadata to physical memory.

VkDevice          =
                  device;
VkQueue                             queue;
VkImage                             sparseImage;
VkAllocationCallbacks*              pAllocator =3D NULL;
VkMemoryRequirements                memoryRequirements =3D {};
uint32_t                            sparseRequirementsCount =3D 0;
VkSparseImageMemoryRequirements*    pSparseReqs =3D NULL;
VkSparseMemoryBind                  binds[MY_IMAGE_ARRAY_SIZE] =3D {};
VkSparseImageMemoryBind             imageBinds[MY_IMAGE_ARRAY_SIZE] =3D {};
uint32_t                            bindCount =3D 0=
;

// Allocate image object (both renderable and sampl=
eable)
const VkImageCreateInfo sparseImageInfo =
=3D
{
    VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,        // =
sType
    NULL,                       =
                // pNext
    VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | ..., // =
flags
    ...
    VK_FORMAT_R8G8B8A8_UNORM,                   // =
format
    ...
    MY_IMAGE_ARRAY_SIZE,                        // =
arrayLayers
    ...
    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
    VK_IMAGE_USAGE_SAMPLED_BIT,                 // =
usage
    ...
};
vkCreateImage(device, &sparseImageInfo, pAllocator, &sparseImage);

// Get memory requirements
vkGetImageMemoryRequirements(
    device,
    sparseImage,
    &memoryRequirements);

// Get sparse image aspect properties
vkGetImageSparseMemoryRequirements(
    device,
    sparseImage,
    &sparseRequirementsCount,
    NULL);

pSparseReqs =3D (VkSparseImageMemoryRequirements*)
    malloc(sparseRequirementsCount * sizeof(=
VkSparseImageMemoryRequirements));

vkGetImageSparseMemoryRequirements(
    device,
    sparseImage,
    &sparseRequirementsCount,
    pSparseReqs);

// Bind LOD level 0 and any required metadata to me=
mory
for (uint32_t i =3D =
0; i < sparseRequirementsCount; ++i)
{
    if (pSparseReqs[i].formatProperties.aspe=
ctMask &
        VK_IMAGE_ASPECT_METADATA_BIT)
    {
        // Metadata must not be combined with other=
 aspects
        assert(pSparseReqs[i].formatProperties.aspectMask =3D=3D
               VK_IMAGE_ASPECT_METADATA_BIT);

        if (pSparseReqs[i].formatProperties.=
flags &
            VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)
        {
            VkSparseMemoryBind* pBind =3D &binds[bindCount];
            pBind->memorySize =3D pSparseReqs[i].imageMipTailSize;
            bindCount++;

            // ... Allocate memory range

            pBind->resourceOffset =3D pSparseReqs[i].imageMipTailOffset;
            pBind->memoryOffset =3D /* allocated=
 memoryOffset */;
            pBind->memory =3D /* allocated memor=
y */;
            pBind->flags =3D VK_SPARSE_MEMORY_BIND_METADATA_BIT;

        }
        else
        {
            // Need a mip tail region per array lay=
er.
            for (uint32_t a =3D 0; a < sparseImageInfo.arrayLayers; ++a)
            {
                VkSparseMemoryBind* pBind =3D &binds[bindCount];
                pBind->memorySize =3D pSparseReqs[i].imageMipTailSize;
                bindCount++;

                // ... Allocate memory range

                pBind->resourceOffset =3D pSparseReqs[i].imageMipTailOff=
set +
                                        (a * pSparseReqs[i].imageMipTailStr=
ide);

                pBind->memoryOffset =3D /* alloc=
ated memoryOffset */;
                pBind->memory =3D /* allocated m=
emory */
                pBind->flags =3D VK_SPARSE_MEMORY_BIND_METADATA_BIT;
            }
        }
    }
    else
    {
        // resource data
        VkExtent3D lod0BlockSize =3D
        {
            AlignedDivide(
                sparseImageInfo.extent.width,
                pSparseReqs[i].formatProperties.imageGranularity.width);
            AlignedDivide(
                sparseImageInfo.extent.height,
                pSparseReqs[i].formatProperties.imageGranularity.height);
            AlignedDivide(
                sparseImageInfo.extent.depth,
                pSparseReqs[i].formatProperties.imageGranularity.depth);
        }
        size_t totalBlocks =3D
            lod0BlockSize.width *
            lod0BlockSize.height *
            lod0BlockSize.depth;

        // Each block is the same size as the align=
ment requirement,
        // calculate total memory size for level 0<=
/span>
        VkDeviceSize lod0MemSize =3D totalBlocks * memoryRequirements.align=
ment;

        // Allocate memory for each array layer
        for (uint32_t a =3D 0; a < sparseImageInfo.arrayLayers; ++a)
        {
            // ... Allocate memory range

            VkSparseImageMemoryBind* pBind =3D &imageBinds[a];
            pBind->subresource.aspectMask =3D pSparseReqs[i].formatPrope=
rties.aspectMask;
            pBind->subresource.mipLevel =3D 0;
            pBind->subresource.arrayLayer =3D a;

            pBind->offset =3D (VkOffset3D){0, 0, 0};
            pBind->extent =3D sparseImageInfo.extent;
            pBind->memoryOffset =3D /* allocated=
 memoryOffset */;
            pBind->memory =3D /* allocated memor=
y */;
            pBind->flags =3D 0;
        }
    }

    free(pSparseReqs);
}

const VkSparseImageOpaqueMemoryBindInfo op=
aqueBindInfo =3D
{
    sparseImage,                                // =
image
    bindCount,                                  // =
bindCount
    binds                                       // =
pBinds
};

const VkSparseImageMemoryBindInfo imageBin=
dInfo =3D
{
    sparseImage,                                // =
image
    sparseImageInfo.arrayLayers,                // =
bindCount
    imageBinds                                  // =
pBinds
};

const VkBindSparseInfo bindSparseInfo =3D
{
    VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,         // =
sType
    NULL,                       =
                // pNext
    ...
    1,                                      =
    // imageOpaqueBindCount
    &opaqueBindInfo,                            // pImageOpaqueBinds
    1,                                      =
    // imageBindCount
    &imageBindInfo,                             // pImageBinds
    ...
};

// vkQueueBindSparse is externally synchronized per=
 queue object.
AcquireQueueOwnership(queue);

// Actually bind memory
vkQueueBindSparse(queue, 1, &bindSparseI=
nfo, VK_NULL_HANDLE);

ReleaseQueueOwnership(queue);

30. Window System Integration (WSI)

This chapter discusses the window system integration (WSI) between the Vulkan API and the various forms of displaying the results of rendering to = a user. Since the Vulkan API can be used without = displaying results, WSI is provided through the use of optional Vulkan extensions. This chapter provides an overview of WSI. See the appendix for additional details of each WSI extension, including which extensions must be enabled in order= to use each of the functions described in this chapter.

30.1. WSI Platform

A platform is an abstraction for a window system, OS, etc. Some examples include MS Windows, Android, and Wayland. The Vulkan API may be integrated in a uni= que manner for each platform.

The Vulkan API does not define any type of platform object. Platform-specific WSI extensions are defined, which contain platform-specific functions for using WSI. Use of these extensions is guarded by preprocessor symbols as defined in th= e Window System-Specific Header Control appendix.=

In order for an application to be compiled to use WSI with a given platf= orm, it must either:

  • #define the appropriate preprocessor symbol prior to including the vulkan.h header file, or

  • include vulkan_core.h and any native platform headers, foll= owed by the appropriate platform-specific header.

The preprocessor symbols and platform-specific headers are defined in th= e Window System Extensions and Headers table.

Each platform-specific extension is an instance extension. The application must enable instance exte= nsions with vkCreateInstance before using them.

30.2. WSI Surface

Native platform surface or window objects are abstracted by surface obje= cts, which are represented by VkSurfaceKHR handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkSurfaceKHR)

The VK_KHR_surface extension declares the VkSurfaceKH= R object, and provides a function for destroying VkSurfaceKHR objects. Separate platform-specific extensions each provide a function for creating = a VkSurfaceKHR object for the respective platform. From the application=E2=80=99s perspective this is an opaque handle, just l= ike the handles of other Vulkan objects.

Note

On certain platforms, the Vulkan loader and ICDs may have conventions that treat the handle as a pointer to a struct that contains the platform-specific information about the surface. This will be described in the documentation for the loader-ICD interface, and in the vk_icd.h header file of the LoaderAndTools source-c= ode repository. This does not affect the loader-layer interface; layers may wrap VkSurfaceKHR objects.

editing-note

TODO: Consider replacing the above note editing note with a pointer to t= he loader spec when it exists. However, the information is not relevant to users of the API nor does it affect conformance of a Vulkan implementation to this spec.

30.2.1. Android Platform

To create a VkSurfaceKHR object for an Android native windo= w, call:

VkResult vkCreateA=
ndroidSurfaceKHR(
    VkInstance                                  instance,
    const VkAndroidSurfaceCreateInfoKHR*  =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance to associate the surface with.

  • pCreateInfo is a pointer to an instance of the VkAndroidSurfaceCreateInfoKHR structure containing parameters affecting the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

During the lifetime of a surface created using a particular ANativeWindow handle any attempts to create another surface fo= r the same ANativeWindow and any attempts to connect to the same ANativeWindow through other platform mechanisms will fail.

Note

In particular, only one VkSurfaceKHR can exist at a time for a given window. Similarly, a native window cannot be used= by both a VkSurfaceKHR and EGLSurface simultaneously.

If successful, vkCreateAndroidSurfaceKHR increments the ANativeWindow=E2=80=99s reference count, and vkDestroySu= rfaceKHR will decrement it.

On Android, when a swapchain=E2=80=99s imageExtent does not= match the surface=E2=80=99s currentExtent, the presentable images will b= e scaled to the surface=E2=80=99s dimensions during presentation. minImageExtent is (1,1), and m= axImageExtent is the maximum image size supported by the consumer. For the system compositor, currentExtent is the window size (i= .e. the consumer=E2=80=99s preferred size).

Valid Usage (Implicit)
  • i= nstance must be a valid VkIn= stance handle

  • pCreateInfo must be a valid poin= ter to a valid VkAndroidSurfaceCreateInfoKHR structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkA= llocationCallbacks structure

  • p= Surface must be a valid pointer to= a VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_NATIVE_WINDOW_IN_USE_KHR

The VkAndroidSurfaceCreateInfoKHR structure is defined as:<= /p>

typedef struct VkAndroidSurface=
CreateInfoKHR {
    VkStructureType                   sType;
    const void*                       pNext;
    VkAndroidSurfaceCreateFlagsKHR    flags;
    struct ANativeWindow*             window=
;
} VkAndroidSurfaceCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • window is a pointer to the ANativeWindow to as= sociate the surface with.

Valid Usage
  • window must point to a valid= Android ANativeWindow.

Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= ANDROID_SURFACE_CREATE_INFO_KHR

  • pNex= t must be NULL

  • flags must be 0

30.2.2. Mir Platform

To create a VkSurfaceKHR object for a Mir window, call:

VkResult vkCreateM=
irSurfaceKHR(
    VkInstance                                  instance,
    const VkMirSurfaceCreateInfoKHR*      =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance to associate the surface with.

  • pCreateInfo is a pointer to an instance of the VkMirSurfaceCreateInfoKHR structure containi= ng parameters affecting the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

Valid Usage (Implicit)
  • insta= nce must be a valid VkInstan= ce handle

  • pC= reateInfo must be a valid pointer = to a valid VkMirSurfaceCreateInfoKHR structure

  • If = pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloc= ationCallbacks structure

  • pSurf= ace must be a valid pointer to a <= code>VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkMirSurfaceCreateInfoKHR structure is defined as:

typedef struct VkMirSurfaceCrea=
teInfoKHR {
    VkStructureType               sType;
    const void*                   pNext;
    VkMirSurfaceCreateFlagsKHR    flags;
    MirConnection*                connection;
    MirSurface*                   mirSurface;
} VkMirSurfaceCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • connection and surface are pointers to the MirConnection and MirSurface for the window to as= sociate the surface with.

Valid Usage
  • connection must point to a v= alid MirConnection.

  • surface must point to a vali= d MirSurface.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_MIR_= SURFACE_CREATE_INFO_KHR

  • pNext must be NULL

  • fl= ags must be 0

On Mir, when a swapchain=E2=80=99s imageExtent does not mat= ch the surface=E2=80=99s currentExtent, the presentable images will be scaled to the su= rface=E2=80=99s dimensions during presentation. minImageExtent is (1,1), and m= axImageExtent is the maximum supported surface size.

30.2.3. Wayland Platform

To create a VkSurfaceKHR object for a Wayland surface, call= :

VkResult vkCreateW=
aylandSurfaceKHR(
    VkInstance                                  instance,
    const VkWaylandSurfaceCreateInfoKHR*  =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance to associate the surface with.

  • pCreateInfo is a pointer to an instance of the VkWaylandSurfaceCreateInfoKHR structure = containing parameters affecting the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

Valid Usage (Implicit)
  • i= nstance must be a valid VkIn= stance handle

  • pCreateInfo must be a valid poin= ter to a valid VkWaylandSurfaceCreateInfoKHR structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkA= llocationCallbacks structure

  • p= Surface must be a valid pointer to= a VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkWaylandSurfaceCreateInfoKHR structure is defined as:<= /p>

typedef struct VkWaylandSurface=
CreateInfoKHR {
    VkStructureType                   sType;
    const void*                       pNext;
    VkWaylandSurfaceCreateFlagsKHR    flags;
    struct wl_display*                displa=
y;
    struct wl_surface*                surfac=
e;
} VkWaylandSurfaceCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • display and surface are pointers to the Waylan= d wl_display and wl_surface to associate the surfac= e with.

Valid Usage
  • display must point to a vali= d Wayland wl_display.

  • surface must point to a vali= d Wayland wl_surface.

Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= WAYLAND_SURFACE_CREATE_INFO_KHR

  • pNex= t must be NULL

  • flags must be 0

On Wayland, currentExtent is undefined (= 0xFFFFFFFF, 0xFFFFFFFF). Whatever the application sets a swapchain=E2=80=99s imageExtent to will be the size of the window, after the first image is presented. minImageExtent is (1,1), and m= axImageExtent is the maximum supported surface size. Any calls to vkGetPhysicalDevice= SurfacePresentModesKHR on a surface created with vkCreateWaylandSurfaceKHR are required to return VK_PRESENT_MODE_MAILBOX_KHR as one of the valid present modes.=

Some Vulkan functions may send protoco= l over the specified wl_display connection when using a swapchain or presentable images created from a VkSurfaceKHR referring to a wl_surface. Applications must therefore ensure that b= oth the wl_display and the wl_surface remain valid for the lifetime of any VkSwapch= ainKHR objects created from a particular wl_display and wl_surf= ace. Also, calling vkQueuePresentKHR will result in Vulka= n sending wl_surface.commit requests to the underlying wl_surface<= /code> of each VkSwapchainKHR objects referenced by pPresentInfo= . If the swapchain is created with a present mode of VK_PRESENT_MODE_MAILBOX_KHR or VK_PRESENT_MODE_IMMEDIATE= _KHR, then the corresponding wl_surface.attach, wl_surface.damage, and wl_surface.commit request must be issued by the implementation during the call to vkQueuePresentKHR and must not be issued by the implementation outside of vkQueuePresentKHR. This ensures that any Wayland requests sent by the client after the call to vkQueuePresentKHR returns will be received by the co= mpositor after the wl_surface.commit. Regardless of the mode of swapchain creation, a new wl_event_queue must be created for each successful vkCreateWaylandSurfaceKHR call, and every Wayland object created by the implementation must be assigned to this event queue. If the platform provides Wayland 1.11 or greater, this must be implemented by the use of Wayland proxy object wrappers, to avoid race conditions.

If the application wishes to synchronize any window changes with a particular frame, such requests must be s= ent to the Wayland display server prior to calling vkQueuePresentKHR. For full control over interactions between Vulkan rendering and other Wayland protocol requests and events, a present mode of VK_PRESENT_MODE_MAILBOX_KHR should be used.

30.2.4. Win32 Platform

To create a VkSurfaceKHR object for a Win32 window, call:

VkResult vkCreateW=
in32SurfaceKHR(
    VkInstance                                  instance,
    const VkWin32SurfaceCreateInfoKHR*    =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance to associate the surface with.

  • pCreateInfo is a pointer to an instance of the VkWin32SurfaceCreateInfoKHR structure containing parameters affecting the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

Valid Usage (Implicit)
  • ins= tance must be a valid VkInst= ance handle

  • = pCreateInfo must be a valid pointe= r to a valid VkWin32SurfaceCreateInfoKHR structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAll= ocationCallbacks structure

  • pSu= rface must be a valid pointer to a= VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkWin32SurfaceCreateInfoKHR structure is defined as:

typedef struct VkWin32SurfaceCr=
eateInfoKHR {
    VkStructureType                 sType;
    const void*                     pNext;
    VkWin32SurfaceCreateFlagsKHR    flags;
    HINSTANCE                       hinstance;
    HWND                            hwnd;
} VkWin32SurfaceCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • hinstance and hwnd are the Win32 HINSTAN= CE and HWND for the window to associate the surface with.

Valid Usage
  • hinstance must be a valid Wi= n32 HINSTANCE.

  • hwnd must be a valid Win32 <= code>HWND.

Valid Usage (Implicit)
  • sType<= /code> must be VK_STRUCTURE_TYPE_WI= N32_SURFACE_CREATE_INFO_KHR

  • pNext<= /code> must be NULL

  • = flags must be 0

With Win32, minImageExtent, maxImageExtent, an= d currentExtent must always eq= ual the window size.

The currentExtent of a Win32 surface must have both width and height greater than 0, or both of them 0.

Note

Due to above restrictions, it is only possible to create a new swapchain= on this platform with imageExtent being equal to the current size= of the window.

The window size may become (0, 0) on this platform (e.g. when the window is minimized), and so a swapchain cannot be created until the size changes.

30.2.5. XCB Platform

To create a VkSurfaceKHR object for an X11 window, using th= e XCB client-side library, call:

VkResult vkCreateX=
cbSurfaceKHR(
    VkInstance                                  instance,
    const VkXcbSurfaceCreateInfoKHR*      =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance to associate the surface with.

  • pCreateInfo is a pointer to an instance of the VkXcbSurfaceCreateInfoKHR structure containing parameters affecting the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

Valid Usage (Implicit)
  • insta= nce must be a valid VkInstan= ce handle

  • pC= reateInfo must be a valid pointer = to a valid VkXcbSurfaceCreateInfoKHR structure

  • If = pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloc= ationCallbacks structure

  • pSurf= ace must be a valid pointer to a <= code>VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkXcbSurfaceCreateInfoKHR structure is defined as:

typedef struct VkXcbSurfaceCrea=
teInfoKHR {
    VkStructureType               sType;
    const void*                   pNext;
    VkXcbSurfaceCreateFlagsKHR    flags;
    xcb_connection_t*             connection;
    xcb_window_t                  window;
} VkXcbSurfaceCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • connection is a pointer to an xcb_connection_t= to the X server.

  • window is the xcb_window_t for the X11 window = to associate the surface with.

Valid Usage
  • connection must point to a v= alid X11 xcb_connection_t.

  • window must be a valid X11 <= code>xcb_window_t.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_XCB_= SURFACE_CREATE_INFO_KHR

  • pNext must be NULL

  • fl= ags must be 0

With Xcb, minImageExtent, maxImageExtent, and currentExtent must always eq= ual the window size.

The currentExtent of an Xcb surface must have both width and height greater than 0, or both of them 0.

Note

Due to above restrictions, it is only possible to create a new swapchain= on this platform with imageExtent being equal to the current size= of the window.

The window size may become (0, 0) on this platform (e.g. when the window is minimized), and so a swapchain cannot be created until the size changes.

Some Vulkan functions may send protoco= l over the specified xcb connection when using a swapchain or presentable images created from a VkSurfaceKHR referring to an xcb window. Applications must therefore ensure the xc= b connection is available to Vulkan for the duration of any functions that manipulate such swapchains or their presentable images, and any functions that build or queue command buffers that operate on such presentable images. Specifically, applications using Vulkan with xcb-based swapchains must

  • Avoid holding a server grab on an xcb connection while waiting for Vulkan operations to complete using a swapchain derived from a different xcb connection referring to the same X server instance. Failing to do so may result in deadlock.<= /p>

30.2.6. Xlib Platform

To create a VkSurfaceKHR object for an X11 window, using th= e Xlib client-side library, call:

VkResult vkCreateX=
libSurfaceKHR(
    VkInstance                                  instance,
    const VkXlibSurfaceCreateInfoKHR*     =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance to associate the surface with.

  • pCreateInfo is a pointer to an instance of the VkXlibSurfaceCreateInfoKHR structure containing the parameters affecting the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

Valid Usage (Implicit)
  • inst= ance must be a valid VkInsta= nce handle

  • p= CreateInfo must be a valid pointer= to a valid VkXlibSurfaceCreateInfoKHR structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllo= cationCallbacks structure

  • pSur= face must be a valid pointer to a = VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkXlibSurfaceCreateInfoKHR structure is defined as:

typedef struct VkXlibSurfaceCre=
ateInfoKHR {
    VkStructureType                sType;
    const void*                    pNext;
    VkXlibSurfaceCreateFlagsKHR    flags;
    Display*                       dpy;
    Window                         window;
} VkXlibSurfaceCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • dpy is a pointer to an Xlib Display connection= to the X server.

  • window is an Xlib Window to associate the surf= ace with.

Valid Usage
  • dpy must point to a valid Xl= ib Display.

  • window must be a valid Xlib = Window.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_XLI= B_SURFACE_CREATE_INFO_KHR

  • pNext must be NULL

  • f= lags must be 0

With Xlib, minImageExtent, maxImageExtent, and currentExtent must always eq= ual the window size.

The currentExtent of an Xlib surface must have both width and height greater than 0, or both of them 0.

Note

Due to above restrictions, it is only possible to create a new swapchain= on this platform with imageExtent being equal to the current size= of the window.

The window size may become (0, 0) on this platform (e.g. when the window is minimized), and so a swapchain cannot be created until the size changes.

Some Vulkan functions may send protoco= l over the specified Xlib Display connection when using a swapchain or presentable image= s created from a VkSurfaceKHR referring to an Xlib window. Applications must therefore ensure the di= splay connection is available to Vulkan for the duration of any functions that manipulate such swapchains or their presentable images, and any functions that build or queue command buffers that operate on such presentable images. Specifically, applications using Vulkan with Xlib-based swapchains must

  • Avoid holding a server grab on a display connection while waiting for Vulkan operations to complete using a swapchain derived from a different display connection referring to the same X server instance. Failing to do so may result in deadlock.<= /p>

Some implementations may require threads to implement some presentation modes so applications must call XIn= itThreads() before calling any other Xlib functions.

30.2.7. iOS Platform

To create a VkSurfaceKHR object for an iOS UIView, call:

VkResult vkCreateI=
OSSurfaceMVK(
    VkInstance                                  instance,
    const VkIOSSurfaceCreateInfoMVK*      =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance with which to associate the surfac= e.

  • pCreateInfo is a pointer to an instance of the VkIOSSurfaceCreateInfoMVK structure containi= ng parameters affecting the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

Valid Usage (Implicit)
  • insta= nce must be a valid VkInstan= ce handle

  • pC= reateInfo must be a valid pointer = to a valid VkIOSSurfaceCreateInfoMVK structure

  • If = pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloc= ationCallbacks structure

  • pSurf= ace must be a valid pointer to a <= code>VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_NATIVE_WINDOW_IN_USE_KHR

The VkIOSSurfaceCreateInfoMVK structure i= s defined as:

typedef struct VkIOSSurfaceCrea=
teInfoMVK {
    VkStructureType               sType;
    const void*                   pNext;
    VkIOSSurfaceCreateFlagsMVK    flags;
    const void*                   pView;
} VkIOSSurfaceCreateInfoMVK;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • pView is a reference to a UIView object which = will display this surface. This UIView must be backed b= y a CALayer instance of type CAMetalLayer.

Valid Usage
  • pView must be a valid = UIView and must be backed by a CALayer instance of type CAMetalLayer.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_IOS_= SURFACE_CREATE_INFO_MVK

  • pNext must be NULL

  • fl= ags must be 0

30.2.8. macOS Platform

To create a VkSurfaceKHR object for a macOS NSView, call:

VkResult vkCreateM=
acOSSurfaceMVK(
    VkInstance                                  instance,
    const VkMacOSSurfaceCreateInfoMVK*    =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance with which to associate the surfac= e.

  • pCreateInfo is a pointer to an instance of the VkMacOSSurfaceCreateInfoMVK structure cont= aining parameters affecting the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

Valid Usage (Implicit)
  • ins= tance must be a valid VkInst= ance handle

  • = pCreateInfo must be a valid pointe= r to a valid VkMacOSSurfaceCreateInfoMVK structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAll= ocationCallbacks structure

  • pSu= rface must be a valid pointer to a= VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_NATIVE_WINDOW_IN_USE_KHR

The VkMacOSSurfaceCreateInfoMVK structu= re is defined as:

typedef struct VkMacOSSurfaceCr=
eateInfoMVK {
    VkStructureType                 sType;
    const void*                     pNext;
    VkMacOSSurfaceCreateFlagsMVK    flags;
    const void*                     pView;
} VkMacOSSurfaceCreateInfoMVK;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • pView is a reference to a NSView object which = will display this surface. This NSView must be backed b= y a CALayer instance of type CAMetalLayer.

Valid Usage
  • pView must be a valid = NSView and must be backed by a CALayer instance of type CAMetalLayer.

Valid Usage (Implicit)
  • sType<= /code> must be VK_STRUCTURE_TYPE_MA= COS_SURFACE_CREATE_INFO_MVK

  • pNext<= /code> must be NULL

  • = flags must be 0

30.2.9. VI Platform

To create a VkSurfaceKHR object for an nn::vi::Layer, query the layer=E2=80=99s native handle using nn::vi::GetNativeWindow, and then ca= ll:

VkResult vkCreateV=
iSurfaceNN(
    VkInstance                                  instance,
    const VkViSurfaceCreateInfoNN*        =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance with which to associate the surfac= e.

  • pCreateInfo is a pointer to an instance of the VkViSurfaceCreateInfoNN structure containing parameters affect= ing the creation of the surface object.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface object is returned.

During the lifetime of a surface created using a particular nn::vi::NativeWindowHandle any attem= pts to create another surface for the same nn::vi::Layer a= nd any attempts to connect to the same nn::vi::Layer th= rough other platform mechanisms will have undefined results.

The currentExtent of a VI surface is always undefined. Applications are expected to choose an appropriate size for the swapchain= =E2=80=99s imageExtent (e.g., by matching the the result of a call to nn::vi::GetDisplayResolution).

Valid Usage (Implicit)
  • instanc= e must be a valid VkInstance= handle

  • pCre= ateInfo must be a valid pointer to= a valid VkViSurfaceCreateInfoNN structure

  • If pA= llocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocat= ionCallbacks structure

  • pSurfac= e must be a valid pointer to a VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_NATIVE_WINDOW_IN_USE_KHR

The VkViSurfaceCreateInfoNN structure is defined as:

typedef struct VkViSurfaceCreat=
eInfoNN {
    VkStructureType             sType;
    const void*                 pNext;
    VkViSurfaceCreateFlagsNN    flags;
    void*                       window;
} VkViSurfaceCreateInfoNN;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • window is the nn::vi::Nativ= eWindowHandle for the nn::vi::Layer with which to associat= e the surface.

Valid Usage
  • window must be a valid nn::vi::NativeWindowHandle

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_VI_SUR= FACE_CREATE_INFO_NN

  • pNext must be NULL

  • flag= s must be 0

30.2.10. Platform-Independent = Information

Once created, VkSurfaceKHR objects can be used in this and other extensions, in particular the VK_KHR_swapchain<= /code> extension.

Several WSI functions return VK_ERROR_SURFACE_LOST_KHR if t= he surface becomes no longer available. After such an error, the surface (and any child swapchain, if one exists) should be destroyed, as there is no way t= o restore them to a not-lost state. Applications may attempt to create a new = VkSurfaceKHR using the same native platform window object, but whether such re-creation will succeed is platform-dependent and may depend on the = reason the surface became unavailable. A lost surface does not otherwise cause devices to be lost.

To destroy a VkSurfaceKHR object, call:

void vkDestroySurfaceKHR(
    VkInstance                                  instance,
    VkSurfaceKHR                                surface,
    const VkAllocationCallbacks*          =
      pAllocator);
  • instance is the instance used to create the surface.

  • surface is the surface to destroy.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

Destroying a VkSurfaceKHR merely severs the connection betw= een Vulkan and the native surface, and does not imply destroying the native surface, closing a window, or similar behavior.

Valid Usage
  • All VkSwapchainKHR objects created for surface must have been destroyed prior to destroying surface

  • If VkAllocationCallbacks were provided when surface was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when surface was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • instanc= e must be a valid VkInstance= handle

  • If surfa= ce is not VK_NULL_HANDLE, surface <= strong class=3D"purple">must be a valid VkSurfaceKHR = handle

  • If pA= llocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocat= ionCallbacks structure

  • If surface<= /code> is a valid handle, it must have be= en created, allocated, or retrieved from instance

Host Synchronization
  • Host access to surface must be externally synchronized

30.3. Presenting Directly to Display Devices

In some environments applications can = also present Vulkan rendering directly to display devices without using an intermediate windowing system. This can be useful for embedded applicati= ons, or implementing the rendering/presentation backend of a windowing system using Vulkan. The VK_KHR_display extension provides the functionality necess= ary to enumerate display devices and create VkSurfaceKHR objects that= target displays.

30.3.1. Display Enumeration

Displays are represented by VkDisplayKHR handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDisplayKHR)

Various functions are provided for enumerating the available display dev= ices present on a Vulkan physical device. To query information about the available displays, call:

VkResult vkGetPhys=
icalDeviceDisplayPropertiesKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pPropertyCount,
    VkDisplayPropertiesKHR*                     pProperties);
  • physicalDevice is a physical device.

  • pPropertyCount is a pointer to an integer related to the nu= mber of display devices available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkDisplayPropertiesKHR structures.

If pProperties is NULL, then the number of dis= play devices available for physicalDevice is returned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return= the variable is overwritten with the number of structures actually written to pProperties. If the value of pPropertyCount is less than the number of disp= lay devices for physicalDevice, at most pPropertyCount structures will be written. If pPropertyCount is smaller than the number of display device= s available for physicalDevice, VK_INCOMPLETE will = be returned instead of VK_SUCCESS to indicate that not all the available v= alues were returned.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pPropertyCount must be a valid pointer to a uint32_t value

  • If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, p= Properties must be a valid pointer= to an array of pPropertyCount VkDisplayPropertiesKHR structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplayPropertiesKHR structure is defined as:

typedef struct VkDisplayPropert=
iesKHR {
    VkDisplayKHR                  display;
    const =
char*                   displayName;
    VkExtent2D                    physicalDimensions;
    VkExtent2D                    physicalResolution;
    VkSurfaceTransformFlagsKHR    supportedTransforms;
    VkBool32                      planeReorderPossible;
    VkBool32                      persistentContent;
} VkDisplayPropertiesKHR;
  • display is a handle that is used to refer to the display de= scribed here. This handle will be valid for the lifetime of the Vulkan instance.

  • displayName is a pointer to a NULL-terminated string contai= ning the name of the display. Generally, this will be the name provided by the display=E2=80=99s EDID. It can be NULL if no suitabl= e name is available. If not NULL, the memory it points to = must remain accessible as long as display is valid.

  • physicalDimensions describes the physical width and height = of the visible portion of the display, in millimeters.

  • physicalResolution describes the physical, native, or prefe= rred resolution of the display.

Note

For devices which have no natural value to return here, implementations should return the maximum resolution supp= orted.

  • supportedTransforms tells which transforms are supported by= this display. This will contain one or more of the bits from VkSurfaceTransformFlagsKHR.

  • planeReorderPossible tells whether the planes on this displ= ay can have their z order changed. If this is VK_TRUE, the application c= an re-arrange the planes on this display in any order relative to each other.

  • persistentContent tells whether the display supports self-refresh/internal buffering. If this is true, the application can subm= it persistent present operations on swapchains created against this display.

Note

Persistent presents may have higher la= tency, and may use less power when the screen content is updated infrequently, or when only a portion of the screen needs to be updated in most frames.

To query information about the available displays, call:

VkResult vkGetPhys=
icalDeviceDisplayProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pPropertyCount,
    VkDisplayProperties2KHR*                    pProperties);
  • physicalDevice is a physical device.

  • pPropertyCount is a pointer to an integer related to the nu= mber of display devices available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkDisplayProperties2KHR structures.

vkGetPhysicalDeviceDisplayProperties2KHR behaves similarly = to vkGetPhysicalDeviceDisplayProperti= esKHR, with the ability to return extended information via chained output structures.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pPropertyCount must be a valid pointer to a uint32_t value

  • If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, = pProperties must be a valid pointe= r to an array of pPropertyCount VkDisplayProperties2KHR<= /code> structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplayProperties2KHR structure is defined as:

typedef struct VkDisplayPropert=
ies2KHR {
    VkStructureType           sType;
    void*                     pNext;
    VkDisplayPropertiesKHR    displayProperties;
} VkDisplayProperties2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • displayProperties is an instance of the VkDisplayPropertiesKHR structure.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DISPLA= Y_PROPERTIES_2_KHR

  • pNext must be NULL

Acquiring and Releasing Displa= ys

On some platforms, access to displays is limited to a single process or native driver instance. On such platforms, some or all of the displays may not be available to Vulkan if they are already in use by a native windowing system or other application.

To acquire permission to directly access a display in Vulkan from an X11 server, call:

VkResult vkAcquire=
XlibDisplayEXT(
    VkPhysicalDevice                            physicalDevice,
    Display*                                    dpy,
    VkDisplayKHR                                display);
  • physicalDevice The physical device the display is on.

  • dpy A connection to the X11 server that currently owns display.

  • display The display the caller wishes to control in Vulkan.=

All permissions necessary to control the display are granted to the Vulk= an instance associated with physicalDevice until the display is r= eleased or the X11 connection specified by dpy is terminated. Permission to access the display may be t= emporarily revoked during periods when the X11 server from which control was acquired itself looses access to display. During such periods, operations which require access to the display must fail with an approriate error code. If the X11 server associated with dpy does not own displ= ay, or if permission to access it has already been acquired by another entity, the call must return the error code VK_= ERROR_INITIALIZATION_FAILED.

Note

One example of when an X11 server loses access to a display is when it l= oses ownership of its virtual terminal.

Valid Usage (Implicit)
  • physicalDevice must be a valid = VkPhysicalDevice handle

  • dpy must be a valid pointer to a Dis= play value

  • disp= lay must be a valid VkDispla= yKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_INITIALIZATION_FAILED

When acquiring displays from an X11 server, an application may also wish= to enumerate and identify them using a native handle rather than a VkDisplayKHR handle. To determine the VkDisplayKHR handle corresponding to an X11 R= andR Output, call:

VkResult vkGetRand=
ROutputDisplayEXT(
    VkPhysicalDevice                            physicalDevice,
    Display*                                    dpy,
    RROutput                                    rrOutput,
    VkDisplayKHR*                               pDisplay);
  • physicalDevice The physical device to query the display han= dle on.

  • dpy A connection to the X11 server from which rrOutpu= t was queried.

  • rrOutput An X11 RandR output ID.

  • pDisplay The corresponding VkDisplayKHR h= andle will be returned here.

If there is no VkDisplayKHR corresponding to rrO= utput on physicalDevice, VK_NULL_HANDLE must be returned in pDisplay.

Valid Usage (Implicit)
  • = physicalDevice must be a val= id VkPhysicalDevice handle

  • dpy must be a valid pointer to a = Display value

  • = pDisplay must be a valid pointer t= o a VkDisplayKHR handle

Return Codes
Success
  • VK_SUCCESS

To release a previously acquired display, call:

VkResult vkRelease=
DisplayEXT(
    VkPhysicalDevice                            physicalDevice,
    VkDisplayKHR                                display);
  • physicalDevice The physical device the display is on.

  • display The display to release control of.

Valid Usage (Implicit)
  • p= hysicalDevice must be a valid VkPhysicalDevice handle

  • display<= /code> must be a valid VkDisplayKHR= handle

Return Codes
Success
  • VK_SUCCESS

Display Planes

Images are presented to individual planes on a display. Devices must support at least one plane o= n each display. Planes can be stacked and blended to comp= osite multiple images on one display. Devices may support only a fixed stacking= order and fixed mapping between planes and displays, or they may allow ar= bitrary application specified stacking orders and mappings between planes and displays. To query the properties of device display planes, call:

VkResult vkGetPhys=
icalDeviceDisplayPlanePropertiesKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pPropertyCount,
    VkDisplayPlanePropertiesKHR*                pProperties);
  • physicalDevice is a physical device.

  • pPropertyCount is a pointer to an integer related to the nu= mber of display planes available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkDisplayPlanePropertiesKHR structures.

If pProperties is NULL, then the number of dis= play planes available for physicalDevice is returned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return= the variable is overwritten with the number of structures actually written to pProperties. If the value of pPropertyCount is less than the number of disp= lay planes for physicalDevice, at most pPropertyCount= structures will be written.

Valid Usage (Implicit)
  • physicalDevice must= be a valid VkPhysicalDevice handle

  • pPropertyCount must= be a valid pointer to a uint32_t value

  • If the value referenced by pPropertyCount is no= t 0, and pProperties is not NULL, pProperties must be a valid po= inter to an array of pPropertyCount VkDisplayPlaneProper= tiesKHR structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplayPlanePropertiesKHR structure is defined as:

typedef struct VkDisplayPlanePr=
opertiesKHR {
    VkDisplayKHR    currentDisplay;
    uint32_t        currentStackIndex;
} VkDisplayPlanePropertiesKHR;
  • currentDisplay is the handle of the display the plane is cu= rrently associated with. If the plane is not currently attached to any displays, this will be VK_NULL_HANDLE.

  • currentStackIndex is the current z-order of the plane. This will be between 0 and the value returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR in pPropertyCount.

To query the properties of a device=E2=80=99s display planes, call:

VkResult vkGetPhys=
icalDeviceDisplayPlaneProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pPropertyCount,
    VkDisplayPlaneProperties2KHR*               pProperties);
  • physicalDevice is a physical device.

  • pPropertyCount is a pointer to an integer related to the nu= mber of display planes available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkDisplayPlaneProperties2KHR structures.

vkGetPhysicalDeviceDisplayPlaneProperties2KHR behaves simil= arly to vkGetPhysicalDeviceDisplayPla= nePropertiesKHR, with the ability to return extended information via chained output structures.

Valid Usage (Implicit)
  • physicalDevice mus= t be a valid VkPhysicalDevice handle

  • pPropertyCount mus= t be a valid pointer to a uint32_t value

  • If the value referenced by pPropertyCount is n= ot 0, and pProperties is not NULL, <= code>pProperties must be a valid p= ointer to an array of pPropertyCount VkDisplayPlanePrope= rties2KHR structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplayPlaneProperties2KHR structure is defined as:

typedef struct VkDisplayPlanePr=
operties2KHR {
    VkStructureType                sType;
    void*                          pNext;
    VkDisplayPlanePropertiesKHR    displayPlaneProperties;
} VkDisplayPlaneProperties2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • displayPlaneProperties is an instance of the VkDisplayPlanePropertiesKHR structure.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_D= ISPLAY_PLANE_PROPERTIES_2_KHR

  • pNext= must be NULL

To determine which displays a plane is usable with, call

VkResult vkGetDisp=
layPlaneSupportedDisplaysKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t                                    planeIndex,
    uint32_t*                                   pDisplayCount,
    VkDisplayKHR*                               pDisplays);
  • physicalDevice is a physical device.

  • planeIndex is the plane which the application wishes to use= , and must be in the range [= 0, physical device plane count - 1].

  • pDisplayCount is a pointer to an integer related to the num= ber of displays available or queried, as described below.

  • pDisplays is either NULL or a pointer to an ar= ray of VkDisplayKHR handles.

If pDisplays is NULL, then the number of displ= ays usable with the specified planeIndex for physicalDevice is return= ed in pDisplayCount. Otherwise, pDisplayCount must point to a variable set by the user to the number of elements in the pDisplays array, and on return t= he variable is overwritten with the number of handles actually written to pDisplays. If the value of pDisplayCount is less than the number of displ= ay planes for physicalDevice, at most pDisplayCount = handles will be written. If pDisplayCount is smaller than the number of displays usable= with the specified planeIndex for physicalDevice, VK_INCOMPLETE will be returned instead of VK_SUCCESS to indicate that not al= l the available values were returned.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pDisplayCount must= be a valid pointer to a uint32_t value

  • If the value referenced by pDisplayCount is not 0<= /code>, and pDisplays is not NULL, pDisplay= s must be a valid pointer to an ar= ray of pDisplayCount VkDisplayKHR handles

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Additional properties of displays are queried using specialized query functions.

Display Modes

Display modes are represented by VkDisplayModeKHR handles:<= /p>

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDisplayModeKHR)

Each display has one or more supported modes associated with it by defau= lt. These built-in modes are queried by calling:

VkResult vkGetDisp=
layModePropertiesKHR(
    VkPhysicalDevice                            physicalDevice,
    VkDisplayKHR                                display,
    uint32_t*                                   pPropertyCount,
    VkDisplayModePropertiesKHR*                 pProperties);
  • physicalDevice is the physical device associated with display.

  • display is the display to query.

  • pPropertyCount is a pointer to an integer related to the nu= mber of display modes available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkDisplayModePropertiesKHR structures.

If pProperties is NULL, then the number of dis= play modes available on the specified display for physicalDevice is re= turned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return= the variable is overwritten with the number of structures actually written to pProperties. If the value of pPropertyCount is less than the number of disp= lay modes for physicalDevice, at most pPropertyCount = structures will be written. If pPropertyCount is smaller than the number of display modes available on the specified display for physicalDevice, VK_INCOMPLETE will be returned instead of VK_SUCCESS to indicate that not all the available values were returned.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplayModePropertiesKHR structure is defined as:

typedef struct VkDisplayModePro=
pertiesKHR {
    VkDisplayModeKHR              displayMode;
    VkDisplayModeParametersKHR    parameters;
} VkDisplayModePropertiesKHR;
  • displayMode is a handle to the display mode described in th= is structure. This handle will be valid for the lifetime of the Vulkan instance.

  • parameters is a VkDisplayModePa= rametersKHR structure describing the display parameters associated with displayMode.=

To query the properties of a device=E2=80=99s built-in display modes, ca= ll:

VkResult vkGetDisp=
layModeProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    VkDisplayKHR                                display,
    uint32_t*                                   pPropertyCount,
    VkDisplayModeProperties2KHR*                pProperties);
  • physicalDevice is the physical device associated with display.

  • display is the display to query.

  • pPropertyCount is a pointer to an integer related to the nu= mber of display modes available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkDisplayModeProperties2KHR structures.

vkGetDisplayModeProperties2KHR behaves similarly to vkGetDisplayModePropertiesKHR, with the = ability to return extended information via chained output structures.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplayModeProperties2KHR structure is defined as:

typedef struct VkDisplayModePro=
perties2KHR {
    VkStructureType               sType;
    void*                         pNext;
    VkDisplayModePropertiesKHR    displayModeProperties;
} VkDisplayModeProperties2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • displayModeProperties is an instance of the VkDisplayModePropertiesKHR structure.

Valid Usage (Implicit)
  • sType<= /code> must be VK_STRUCTURE_TYPE_DI= SPLAY_MODE_PROPERTIES_2_KHR

  • pNext<= /code> must be NULL

The VkDisplayModeParametersKHR structure is defined as:

typedef struct VkDisplayModePar=
ametersKHR {
    VkExtent2D    visibleRegion;
    uint32_t      refreshRate;
} VkDisplayModeParametersKHR;
  • visibleRegion is the 2D extents of the visible region.

  • refreshRate is a uint32_t that is the number o= f times the display is refreshed each second multiplied by 1000.

Note

For example, a 60Hz display mode would report a refreshRate= of 60,000.

Valid Usage
  • The width member of visibleRegion must be greater than 0

  • The height member of visibleRegion must be greater than 0

  • refreshRate must be greater = than 0

Additional modes may also be created b= y calling:

VkResult vkCreateD=
isplayModeKHR(
    VkPhysicalDevice                            physicalDevice,
    VkDisplayKHR                                display,
    const VkDisplayModeCreateInfoKHR*     =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDisplayModeKHR*                           pMode);
  • physicalDevice is the physical device associated with display.

  • display is the display to create an additional mode for.

  • pCreateInfo is a VkDisplayModeC= reateInfoKHR structure describing the new mode to create.

  • pAllocator is the allocator used for host memory allocated = for the display mode object when there is no more specific allocator available (see Memory Allocation).

  • pMode returns the handle of the mode created.

Valid Usage (Implicit)
  • physicalDevice must be a valid <= code>VkPhysicalDevice handle

  • displ= ay must be a valid VkDisplay= KHR handle

  • p= CreateInfo must be a valid pointer= to a valid VkDisplayModeCreateInfoKHR structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllo= cationCallbacks structure

  • pMode must be a valid pointer to a = VkDisplayModeKHR handle

Host Synchronization
  • Host access to display must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INITIALIZATION_FAILED

The VkDisplayModeCreateInfoKHR structure is defined as:

typedef struct VkDisplayModeCre=
ateInfoKHR {
    VkStructureType                sType;
    const void*                    pNext;
    VkDisplayModeCreateFlagsKHR    flags;
    VkDisplayModeParametersKHR     parameters;
} VkDisplayModeCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use, and must be zero.

  • parameters is a VkDisplayModePa= rametersKHR structure describing the display parameters to use in creating the new mode. If the parameters are not compatible with the specified display, the implementation must return VK_ERROR= _INITIALIZATION_FAILED.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DIS= PLAY_MODE_CREATE_INFO_KHR

  • pNext must be NULL

  • f= lags must be 0

  • parameters must be a valid VkDisplayModeParametersKHR structure

Applications that wish to present directly to a display must select which layer, or =E2=80=9Cplane=E2=80=9D of the display they wish to target, and a= mode to use with the display. Each display supports at least one plane. The capabilities of a given mode and plane combination are determined by calling:

VkResult vkGetDisp=
layPlaneCapabilitiesKHR(
    VkPhysicalDevice                            physicalDevice,
    VkDisplayModeKHR                            mode,
    uint32_t                                    planeIndex,
    VkDisplayPlaneCapabilitiesKHR*              pCapabilities);
  • physicalDevice is the physical device associated with display

  • mode is the display mode the application intends to program= when using the specified plane. Note this parameter also implicitly specifies a display.

  • planeIndex is the plane which the application intends to us= e with the display, and is less than the number of display planes supported by the device.

  • pCapabilities is a pointer to a VkDisplayPlaneCapabilitiesKHR structure = in which the capabilities are returned.

Valid Usage (Implicit)
  • physicalDevice must be= a valid VkPhysicalDevice handle

  • mode must be a valid VkDis= playModeKHR handle

  • = pCapabilities must be a= valid pointer to a VkDisplayPlaneCapabilitiesKHR structure

Host Synchronization
  • Host access to mode must = be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplayPlaneCapabilitiesKHR structure is defined as:<= /p>

typedef struct VkDisplayPlaneCa=
pabilitiesKHR {
    VkDisplayPlaneAlphaFlagsKHR    supportedAlpha;
    VkOffset2D                     minSrcPosition;
    VkOffset2D                     maxSrcPosition;
    VkExtent2D                     minSrcExtent;
    VkExtent2D                     maxSrcExtent;
    VkOffset2D                     minDstPosition;
    VkOffset2D                     maxDstPosition;
    VkExtent2D                     minDstExtent;
    VkExtent2D                     maxDstExtent;
} VkDisplayPlaneCapabilitiesKHR;
  • supportedAlpha is a bitmask of VkDisplayPlaneAlphaFlagBitsKHR describi= ng the supported alpha blending modes.

  • minSrcPosition is the minimum source rectangle offset suppo= rted by this plane using the specified mode.

  • maxSrcPosition is the maximum source rectangle offset suppo= rted by this plane using the specified mode. The x and y components of maxSrcPosition must each be greater than or equal to the x and y components o= f minSrcPosition, respectively.

  • minSrcExtent is the minimum source rectangle size supported= by this plane using the specified mode.

  • maxSrcExtent is the maximum source rectangle size supported= by this plane using the specified mode.

  • minDstPosition, maxDstPosition, minDstEx= tent, maxDstExtent all have similar semantics to their corresponding *Src* equivalents, but apply to the output region within the m= ode rather than the input region within the source image. Unlike the *Src* offsets, minDstPosition and maxDstPosition may contain n= egative values.

The minimum and maximum position and extent fields describe the implementation limits, if any, as they apply to the specified display mode and plane. Vendors may support displaying a subset o= f a swapchain=E2=80=99s presentable images on the specified display plane. This is expressed by returning minSrcPosition, maxSrcPos= ition, minSrcExtent, and maxSrcExtent values that indica= te a range of possible positions and sizes may be used = to specify the region within the presentable images that source pixels will be read from when creating a swapchain on the specified display mode and plane.

Vendors may also support mapping the p= resentable images=E2=80=99 content to a subset or superset of the visible region in the specified display mode. This is expressed by returning minDstPosition, maxDstPos= ition, minDstExtent and maxDstExtent values that indicat= e a range of possible positions and sizes may be used = to describe the region within the display mode that the source pixels will be mapped to.

Other vendors may support only a 1-1 m= apping between pixels in the presentable images and the display mode. This may be indicated by returning (0,0) for minSrcPosition, maxSrcPosition, minDstPosition, and maxDstP= osition, and (display mode width, display mode height) for minSrcExtent, maxSrcExtent, minDstExtent, and maxDstExten= t.

These values indicate the limits of the implementation=E2=80=99s individ= ual fields. Not all combinations of values within the offset and extent ranges returned in VkDisplayPlaneCapabilitiesKHR are guaranteed to be supporte= d. Vendors may still fail presentation reque= sts that specify unsupported combinations.

To query the capabilities of a given mode and plane combination, call:

VkResult vkGetDisp=
layPlaneCapabilities2KHR(
    VkPhysicalDevice                            physicalDevice,
    const VkDisplayPlaneInfo2KHR*         =
      pDisplayPlaneInfo,
    VkDisplayPlaneCapabilities2KHR*             pCapabilities);
  • physicalDevice is the physical device associated with pDisplayPlaneInfo.

  • pDisplayPlaneInfo is a pointer to an instance of the VkDisplayPlaneInfo2KHR structure describing the= plane and mode.

  • pCapabilities is a pointer to a VkDisplayPlaneCapabilities2KHR structur= e in which the capabilities are returned.

vkGetDisplayPlaneCapabilities2KHR behaves similarly to vkGetDisplayPlaneCapabilitiesKHR, wit= h the ability to specify extended inputs via chained input structures, and to return extended information via chained output structures.

Valid Usage (Implicit)
  • physicalDevice must b= e a valid VkPhysicalDevice handle

  • pDisplayPlaneInfo must be a valid pointer to a valid VkDisplayPlaneInfo2KHR stru= cture

  • pCapabilities must be = a valid pointer to a VkDisplayPlaneCapabilities2KHR structure<= /p>

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplayPlaneInfo2KHR structure is defined as:

typedef struct VkDisplayPlaneIn=
fo2KHR {
    VkStructureType     sType;
    const void*         pNext;
    VkDisplayModeKHR    mode;
    uint32_t            planeIndex;
} VkDisplayPlaneInfo2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • mode is the display mode the application intends to program= when using the specified plane.

Note

This parameter also implicitly specifies a display.

  • planeIndex is the plane which the application intends to us= e with the display.

The members of VkDisplayPlaneInfo2KHR correspond to the arg= uments to vkGetDisplayPlaneCapabilitiesKHR, wit= h sType and pNext added for extensibility.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DISPLAY= _PLANE_INFO_2_KHR

  • pNext must be NULL

  • mode must be a valid VkDisplayModeKH= R handle

Host Synchronization
  • Host access to mode must = be externally synchronized

The VkDisplayPlaneCapabilities2KHR structure is defined as:=

typedef struct VkDisplayPlaneCa=
pabilities2KHR {
    VkStructureType                  sType;
    void*                            pNext=
;
    VkDisplayPlaneCapabilitiesKHR    capabilities;
} VkDisplayPlaneCapabilities2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • capabilities is an instance of the VkDisplayPlaneCapabilitiesKHR structure.=

Valid Usage (Implicit)
  • sTy= pe must be VK_STRUCTURE_TYPE= _DISPLAY_PLANE_CAPABILITIES_2_KHR

  • pNe= xt must be NULL

30.3.2. Display Control

To set the power state of a display, call:

VkResult vkDisplay=
PowerControlEXT(
    VkDevice                                    device,
    VkDisplayKHR                                display,
    const VkDisplayPowerInfoEXT*          =
      pDisplayPowerInfo);
  • device is a logical device associated with display.

  • display is the display whose power state is modified.

  • pDisplayPowerInfo is an instance of = VkDisplayPowerInfoEXT specifying the new power state of display.

Valid Usage (Implicit)
  • devi= ce must be a valid VkDevice<= /code> handle

  • dis= play must be a valid VkDispl= ayKHR handle

  • = pDisplayPowerInfo must be a= valid pointer to a valid VkDisplayPowerInfoEXT structure

Return Codes
Success
  • VK_SUCCESS

The VkDisplayPowerInfoEXT structure is defined as:

typedef struct VkDisplayPowerIn=
foEXT {
    VkStructureType           sType;
    const void*               pNext;
    VkDisplayPowerStateEXT    powerState;
} VkDisplayPowerInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • powerState is a VkDisplayPowerState= EXT value specifying the new power state of the display.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_DISPLAY_= POWER_INFO_EXT

  • pNext= must be NULL

  • pow= erState must be a valid VkDisplayPowerStateEXT value

Possible values of VkDisplayPowerInfoEXT::powerState, specifying the new power state of a display, are:

typedef enum VkDisplayPowerStat=
eEXT {
    VK_DISPLAY_POWER_STATE_OFF_EXT =3D 0,
    VK_DISPLAY_POWER_STATE_SUSPEND_EXT =3D 1=
,
    VK_DISPLAY_POWER_STATE_ON_EXT =3D 2,
} VkDisplayPowerStateEXT;
  • VK_DISPLAY_POWER_STATE_OFF_EXT specifies that the display i= s powered down.

  • VK_DISPLAY_POWER_STATE_SUSPEND_EXT specifies that the displ= ay is put into a low power mode, from which it may be able to transition back to VK_DISPLAY_POWER_STATE_ON_EXT more quickly than if it were = in VK_DISPLAY_POWER_STATE_OFF_EXT. This state may be the same as VK_DI= SPLAY_POWER_STATE_OFF_EXT.

  • VK_DISPLAY_POWER_STATE_ON_EXT specifies that the display is powered on.

30.3.3. Display Surfaces

A complete display configuration includes a mode, one or more display pl= anes and any parameters describing their behavior, and parameters describing som= e aspects of the images associated with those planes. Display surfaces describe the configuration of a single plane within a complete display configuration. To create a VkSurfaceKHR structure for a display surface, call= :

VkResult vkCreateD=
isplayPlaneSurfaceKHR(
    VkInstance                                  instance,
    const VkDisplaySurfaceCreateInfoKHR*  =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSurfaceKHR*                               pSurface);
  • instance is the instance corresponding to the physical devi= ce the targeted display is on.

  • pCreateInfo is a pointer to an instance of the VkDisplaySurfaceCreateInfoKHR structure = specifying which mode, plane, and other parameters to use, as described below.

  • pAllocator is the allocator used for host memory allocated = for the surface object when there is no more specific allocator available (see Memory Allocation).

  • pSurface points to a VkSurfaceKHR handle = in which the created surface is returned.

Valid Usage (Implicit)
  • instance must be a valid VkInstance handle

  • = pCreateInfo must be a valid= pointer to a valid VkDisplaySurfaceCreateInfoKHR structure

  • = If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • pSurface must be a valid point= er to a VkSurfaceKHR handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDisplaySurfaceCreateInfoKHR structure is defined as:<= /p>

typedef struct VkDisplaySurface=
CreateInfoKHR {
    VkStructureType                   sType;
    const void*                       pNext;
    VkDisplaySurfaceCreateFlagsKHR    flags;
    VkDisplayModeKHR                  displayMode;
    uint32_t                          planeIndex;
    uint32_t                          planeStackIndex;
    VkSurfaceTransformFlagBitsKHR     transform;
    float                           =
  globalAlpha;
    VkDisplayPlaneAlphaFlagBitsKHR    alphaMode;
    VkExtent2D                        imageExtent;
} VkDisplaySurfaceCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use, and must be zero.

  • displayMode is a VkDisplayModeKHR han= dle specifying the mode to use when displaying this surface.

  • planeIndex is the plane on which this surface appears.

  • planeStackIndex is the z-order of the plane.

  • transform is a VkSurfaceTran= sformFlagBitsKHR value specifying the transformation to apply to images as part of the scanout operation.

  • globalAlpha is the global alpha value. This value is ignored if alphaMode is not VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR.

  • alphaMode is a VkDisplayPla= neAlphaFlagBitsKHR value specifying the type of alpha blending to use.

  • imageExtent The size of the presentable images to use with = the surface.

Note

Creating a display surface must not mo= dify the state of the displays, planes, or other resources it names. For example, it must not apply the specif= ied mode to be set on the associated display. Application of display configuration occurs as a side effect of presenting to a display surface.

Valid Usage
  • planeIndex must be less than= the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR

  • = If the planeReorderPossible member of the VkDisplayPropertiesKHR structure returned by vkGetPhysicalDeviceDisplayPropertiesKHR for the display corresponding to displayMode is VK_TRUE then planeStackIndex must be less= than the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR; otherwise planeStackIndex must equal t= he currentStackIndex member of VkDisplayPlanePropertiesKHR returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR for the display p= lane corresponding to displayMode

  • If alphaMode is VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR then globalAlpha must be between = 0 and 1, inclusive

  • alphaMode must be 0 or one of the bits present in the supportedAlpha member of VkDisplayPlaneCapabilitiesKHR returned by vkGetDisplayPlaneCapabilitiesKHR for the display p= lane corresponding to displayMode

  • The width and height members of imageExtent= must be less than the maxImageDimensions2D member of VkPhysicalDeviceLimits

Valid Usage (Implicit)

Possible values of VkDisplaySurfaceCreate= InfoKHR::alphaMode, specifying the type of alpha blending to use on a display, are:

typedef enum VkDisplayPlaneAlph=
aFlagBitsKHR {
    VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR =3D 0x0000000=
1,
    VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR =3D 0x0000000=
2,
    VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR =3D 0x0000=
0004,
    VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR =3D 0x00000008,
} VkDisplayPlaneAlphaFlagBitsKHR;
  • VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR specifies that the so= urce image will be treated as opaque.

  • VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR specifies that a glob= al alpha value must be specified that will b= e applied to all pixels in the source image.

  • VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR specifies that the= alpha value will be determined by the alpha channel of the source image=E2=80=99s pixels. If the source format contains no alpha values, no blending will be applied. The source alpha values are not premultiplied into the source image=E2=80= =99s other color channels.

  • VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR is equivalent to VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR, except= the source alpha values are assumed to be premultiplied into the source image=E2=80=99s other color channels.

typedef VkFlags VkDisplayPlaneAlphaFlagsKHR;

VkDisplayPlaneAlphaFlagsKHR is a bitmask type for setting a= mask of zero or more VkDisplayPlaneAlphaFlagBitsKHR= .

30.4. Querying for WSI Support

Not all physical devices will include WSI support. Within a physical device, not all queue families will support presentation. WSI support and compatibility can be dete= rmined in a platform-neutral manner (which determines support for presentation to a particular surface object) and additionally may be determine= d in platform-specific manners (which determine support for presentation on the specified physical device but do not guarantee support for presentation to a particular surface object).

To determine whether a queue family of a physical device supports presentation to a given surface, call:

VkResult vkGetPhys=
icalDeviceSurfaceSupportKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t                                    queueFamilyIndex,
    VkSurfaceKHR                                surface,
    VkBool32*                                   pSupported);
  • physicalDevice is the physical device.

  • queueFamilyIndex is the queue family.

  • surface is the surface.

  • pSupported is a pointer to a VkBool32, which i= s set to VK_TRUE to indicate support, and VK_FALSE otherwi= se.

Valid Usage
  • queueFamilyIndex must be les= s than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • surface must be a valid <= code>VkSurfaceKHR handle

  • pSupported must be a v= alid pointer to a VkBool32 value

  • Bo= th of physicalDevice, and surface must have been created, allocated, or retrieved from t= he same VkInstance

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_SURFACE_LOST_KHR

30.4.1. Android Platform

On Android, all physical devices and queue families must be capable of presentation with any native window. As a result there is no Android-specific query for these capabilities.

30.4.2. Mir Platform

To determine whether a queue family of a physical device supports presentation to the Mir compositor, call:

VkBool32 vkGetPhys=
icalDeviceMirPresentationSupportKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t                                    queueFamilyIndex,
    MirConnection*                              connection);
  • physicalDevice is the physical device.

  • queueFamilyIndex is the queue family index.

  • connection is a pointer to the MirConnection, = and identifies the desired Mir compositor.

This platform-specific function can be= called prior to creating a surface.

Valid Usage
  • queueFamilyIndex must be les= s than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice

Valid Usage (Implicit)
  • physicalDevice must= be a valid VkPhysicalDevice handle

  • connection must be a valid pointer to a MirConnection value

30.4.3. Wayland Platform

To determine whether a queue family of a physical device supports presentation to a Wayland compositor, call:

VkBool32 vkGetPhys=
icalDeviceWaylandPresentationSupportKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t                                    queueFamilyIndex,
    struct wl_display*                      =
    display);
  • physicalDevice is the physical device.

  • queueFamilyIndex is the queue family index.

  • display is a pointer to the wl_display associa= ted with a Wayland compositor.

This platform-specific function can be= called prior to creating a surface.

Valid Usage
  • queueFamilyIndex must be les= s than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice

Valid Usage (Implicit)
  • physicalDevice = must be a valid VkPhysicalDevice handle

  • display must = be a valid pointer to a wl_display value

30.4.4. Win32 Platform

To determine whether a queue family of a physical device supports presentation to the Microsoft Windows desktop, call:

VkBool32 vkGetPhys=
icalDeviceWin32PresentationSupportKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t                                    queueFamilyIndex);
  • physicalDevice is the physical device.

  • queueFamilyIndex is the queue family index.

This platform-specific function can be= called prior to creating a surface.

Valid Usage
  • queueFamilyIndex must be les= s than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice

Valid Usage (Implicit)
  • physicalDevice mu= st be a valid VkPhysicalDevice handle

30.4.5. XCB Platform

To determine whether a queue family of a physical device supports presentation to an X11 server, using the XCB client-side library, call:

VkBool32 vkGetPhys=
icalDeviceXcbPresentationSupportKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t                                    queueFamilyIndex,
    xcb_connection_t*                           connection,
    xcb_visualid_t                              visual_id);
  • physicalDevice is the physical device.

  • queueFamilyIndex is the queue family index.

  • connection is a pointer to an xcb_connection_t= to the X server. visual_id is an X11 visual (xcb_visualid_t).

This platform-specific function can be= called prior to creating a surface.

Valid Usage
  • queueFamilyIndex must be les= s than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice

Valid Usage (Implicit)
  • physicalDevice must= be a valid VkPhysicalDevice handle

  • connection must be a valid pointer to a xcb_connection_t value

30.4.6. Xlib Platform

To determine whether a queue family of a physical device supports presentation to an X11 server, using the Xlib client-side library, call:

VkBool32 vkGetPhys=
icalDeviceXlibPresentationSupportKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t                                    queueFamilyIndex,
    Display*                                    dpy,
    VisualID                                    visualID);
  • physicalDevice is the physical device.

  • queueFamilyIndex is the queue family index.

  • dpy is a pointer to an Xlib Display connection= to the server.

  • visualId is an X11 visual (VisualID).

This platform-specific function can be= called prior to creating a surface.

Valid Usage
  • queueFamilyIndex must be les= s than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice

Valid Usage (Implicit)
  • physicalDevice mus= t be a valid VkPhysicalDevice handle

  • dpy must be a valid = pointer to a Display value

30.4.7. iOS Platform

On iOS, all physical devices and queue families must be capable of presentation with any layer. As a result there is no iOS-specific query for these capabilities.

30.4.8. macOS Platform

On macOS, all physical devices and queue families must be capable of presentation with any layer. As a result there is no macOS-specific query for these capabilities.

30.4.9. VI Platform

On VI, all physical devices and queue families = must be capable of presentation with any layer. As a result there is no VI-specific query for these capabilities.

30.5. Surface Queries

The capabilities of a swapchain targetting a surface are the intersectio= n of the capabilities of the WSI platform, the native window or display, and the physical device. The resulting capabilities can be obtained with the queries listed below in this section. Capabilities that correspond to image creation parameters are not independent of each other: combinations of parameters that are not supporte= d as reported by vkGetPhysicalDevic= eImageFormatProperties are not supported by the surface on that physical device, even if the capabilities taken individually are supported as part of some other parameter combinations.

To query the basic capabilities of a surface, needed in order to create = a swapchain, call:

VkResult vkGetPhys=
icalDeviceSurfaceCapabilitiesKHR(
    VkPhysicalDevice                            physicalDevice,
    VkSurfaceKHR                                surface,
    VkSurfaceCapabilitiesKHR*                   pSurfaceCapabilities);
  • physicalDevice is the physical device that will be associat= ed with the swapchain to be created, as described for vkCreateSwapchainKHR.

  • surface is the surface that will be associated with the swa= pchain.

  • pSurfaceCapabilities is a pointer to an instance of the VkSurfaceCapabilitiesKHR structure in which t= he capabilities are returned.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_SURFACE_LOST_KHR

The VkSurfaceCapabilitiesKHR structure is defined as:

typedef struct VkSurfaceCapabil=
itiesKHR {
    uint32_t                         minImageCount;
    uint32_t                         maxImageCount;
    VkExtent2D                       currentExtent;
    VkExtent2D                       minImageExtent;
    VkExtent2D                       maxImageExtent;
    uint32_t                         maxImageArrayLayers;
    VkSurfaceTransformFlagsKHR       supportedTransforms;
    VkSurfaceTransformFlagBitsKHR    currentTransform;
    VkCompositeAlphaFlagsKHR         supportedCompositeAlpha;
    VkImageUsageFlags                supportedUsageFlags;
} VkSurfaceCapabilitiesKHR;
  • minImageCount is the minimum number of images the specified= device supports for a swapchain created for the surface, and will be at least one.

  • maxImageCount is the maximum number of images the specified= device supports for a swapchain created for the surface, and will be either 0, or greater than or equal to minImageCount. A value of 0 means that there is no limit on the number of images, though there may be limits related to the= total amount of memory used by presentable images.

  • currentExtent is the current width and height of the surfac= e, or the special value (0xFFFFFFFF, 0xFFFFFFFF) indica= ting that the surface size will be determined by the extent of a swapchain targeting the surface.

  • minImageExtent contains the smallest valid swapchain extent= for the surface on the specified device. The width and height of the extent will each be l= ess than or equal to the corresponding width and height of currentExtent, unless currentExtent has the speci= al value described above.

  • maxImageExtent contains the largest valid swapchain extent = for the surface on the specified device. The width and height of the extent will each be g= reater than or equal to the corresponding width and height of minImageExtent. The width and height of the extent will each be g= reater than or equal to the corresponding width and height of currentExtent, unless currentExtent has the speci= al value described above.

  • maxImageArrayLayers is the maximum number of layers present= able images can have for a swapchain created f= or this device and surface, and will be at least one.

  • supportedTransforms is a bitmask of VkSurfaceTransformFlagBitsKHR indicating= the presentation transforms supported for the surface on the specified device. At least one bit will be set.

  • currentTransform is VkSurfac= eTransformFlagBitsKHR value indicating the surface=E2=80=99s current transform relative to the presenta= tion engine=E2=80=99s natural orientation.

  • supportedCompositeAlpha is a bitmask of VkCompositeAlphaFlagBitsKHR, representing = the alpha compositing modes supported by the presentation engine for the surface on the specified device, and at least one bit will be set. Opaque composition can be achieved in any= alpha compositing mode by either using an image format that has no alpha component, or by ensuring that all pixels in the presentable images have an alpha value of 1.0.

  • supportedUsageFlags is a bitmask of V= kImageUsageFlagBits representing the ways the application can= use the presentable images of a swapchain created with VkPresentModeKHR set to VK_PRESENT_MODE_IM= MEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR or VK_PRESENT_MODE_FIFO_RELAXED_KHR for the surface on the specified device. VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT m= ust be included in the set but implementations may support additiona= l usages.

Note

Supported usage flags of a presentable image when using VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR or VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR presentation mod= e are provided by VkSharedPresentSurfaceCapabilitiesKH= R::sharedPresentSupportedUsageFlags.

Note

Formulas such as min(N, maxImageCount) are not correct, since maxImageCount may be zero.

To query the basic capabilities of a surface defined by the core or extensions, call:

VkResult vkGetPhys=
icalDeviceSurfaceCapabilities2KHR(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceSurfaceInfo2KHR*=
      pSurfaceInfo,
    VkSurfaceCapabilities2KHR*                  pSurfaceCapabilities);

vkGetPhysicalDeviceSurfaceCapabilities2KHR behaves similarl= y to vkGetPhysicalDeviceSurfaceCapabi= litiesKHR, with the ability to specify extended inputs via chained input structures, and to return extended information via chained output structures.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pSurfaceInfo must be a valid pointer to a valid VkPhysicalDeviceSurfaceInfo2KHR structure

  • pSurfaceCapabilities must be a valid pointer to a VkSurfaceCapabilities2KHR= structure

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_SURFACE_LOST_KHR

The VkPhysicalDeviceSurfaceInfo2KHR structure is defined as= :

typedef struct VkPhysicalDevice=
SurfaceInfo2KHR {
    VkStructureType    sType;
    const void*        pNext;
    VkSurfaceKHR       surface;
} VkPhysicalDeviceSurfaceInfo2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • surface is the surface that will be associated with the swa= pchain.

The members of VkPhysicalDeviceSurfaceInfo2KHR correspond t= o the arguments to vkGetPhysicalDevice= SurfaceCapabilitiesKHR, with sType and pNext added for extensibility.

Valid Usage (Implicit)
  • sT= ype must be VK_STRUCTURE_TYP= E_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR

  • pN= ext must be NULL

  • surface must be a valid = VkSurfaceKHR handle

The VkSurfaceCapabilities2KHR structure is defined as:

typedef struct VkSurfaceCapabil=
ities2KHR {
    VkStructureType             sType;
    void*                       pNext;
    VkSurfaceCapabilitiesKHR    surfaceCapabilities;
} VkSurfaceCapabilities2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • surfaceCapabilities is a structure of type VkSurfaceCapabilitiesKHR describing the capab= ilities of the specified surface.

Valid Usage (Implicit)

The VkSharedPresentSurfaceCapabilitiesKHR structure is defi= ned as:

typedef struct VkSharedPresentS=
urfaceCapabilitiesKHR {
    VkStructureType      sType;
    void*                pNext;
    VkImageUsageFlags    sharedPresentSupportedUsageFlags;
} VkSharedPresentSurfaceCapabilitiesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • sharedPresentSupportedUsageFlags is a bitmask of VkImageUsageFlagBits representing the ways the ap= plication can use the shared presentable image from a swapchain created with VkPresentModeKHR set to VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR or VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR for the surface = on the specified device. VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT m= ust be included in the set but implementations may support additiona= l usages.

Valid Usage (Implicit)
  • sType must be VK_STRUCTU= RE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR

To query the basic capabilities of a surface, needed in order to create = a swapchain, call:

VkResult vkGetPhys=
icalDeviceSurfaceCapabilities2EXT(
    VkPhysicalDevice                            physicalDevice,
    VkSurfaceKHR                                surface,
    VkSurfaceCapabilities2EXT*                  pSurfaceCapabilities);
  • physicalDevice is the physical device that will be associat= ed with the swapchain to be created, as described for vkCreateSwapchainKHR.

  • surface is the surface that will be associated with the swa= pchain.

  • pSurfaceCapabilities is a pointer to an instance of the VkSurfaceCapabilities2EXT structure in which= the capabilities are returned.

vkGetPhysicalDeviceSurfaceCapabilities2EXT behaves similarl= y to vkGetPhysicalDeviceSurfaceCapabi= litiesKHR, with the ability to return extended information by adding extension structures to the pNext chain of its pSurfaceCapabilities parameter.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_SURFACE_LOST_KHR

The VkSurfaceCapabilities2EXT structure is defined as:

typedef struct VkSurfaceCapabil=
ities2EXT {
    VkStructureType                  sType;
    void*                            pNext=
;
    uint32_t                         minImageCount;
    uint32_t                         maxImageCount;
    VkExtent2D                       currentExtent;
    VkExtent2D                       minImageExtent;
    VkExtent2D                       maxImageExtent;
    uint32_t                         maxImageArrayLayers;
    VkSurfaceTransformFlagsKHR       supportedTransforms;
    VkSurfaceTransformFlagBitsKHR    currentTransform;
    VkCompositeAlphaFlagsKHR         supportedCompositeAlpha;
    VkImageUsageFlags                supportedUsageFlags;
    VkSurfaceCounterFlagsEXT         supportedSurfaceCounters;
} VkSurfaceCapabilities2EXT;

All members of VkSurfaceCapabilities2EXT are identical to t= he corresponding members of VkSurfaceCapabilitiesKHR= where one exists. The remaining members are:

  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • supportedSurfaceCounters is a bitmask of VkSurfaceCounterFlagBitsEXT indicating the= supported surface counter types.

Valid Usage
  • = supportedSurfaceCounters must not include VK_SURFACE_COUNTER_VBLANK_EXT unless the surface queried is a display surface.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_SURF= ACE_CAPABILITIES_2_EXT

  • pNext must be NULL

Bits which can be set in VkSurfaceCapabilities2EXT::supportedSu= rfaceCounters, indicating supported surface counter types, are:

typedef enum VkSurfaceCounterFl=
agBitsEXT {
    VK_SURFACE_COUNTER_VBLANK_EXT =3D 0x00000001=
,
} VkSurfaceCounterFlagBitsEXT;
  • VK_SURFACE_COUNTER_VBLANK_EXT specifies a counter increment= ing once every time a vertical blanking period occurs on the display associated with the surface.

typedef VkFlags VkSurfaceCounterFlagsEXT;

VkSurfaceCounterFlagsEXT is a bitmask type for setting a ma= sk of zero or more VkSurfaceCounterFlagBitsEXT.

Bits which may be set in VkSurfaceCapabilitiesKHR::supportedTran= sforms indicating the presentation transforms supported for the surface on the specified device, and possible values of VkSurfaceCapabilitiesKHR::currentTransf= orm is indicating the surface=E2=80=99s current transform relative to the presentation engine=E2= =80=99s natural orientation, are:

typedef enum VkSurfaceTransform=
FlagBitsKHR {
    VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR =3D 0x0000000=
1,
    VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR =3D 0x000000=
02,
    VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR =3D 0x00000=
004,
    VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR =3D 0x00000=
008,
    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR =3D =
0x00000010,
    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR =3D 0x00000020,
    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR =3D 0x00000040,
    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR =3D 0x00000080,
    VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR =3D 0x00000100=
,
} VkSurfaceTransformFlagBitsKHR;
  • VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR specifies that image = content is presented without being transformed.

  • VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR specifies that image content is rotated 90 degrees clockwise.

  • VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR specifies that imag= e content is rotated 180 degrees clockwise.

  • VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR specifies that imag= e content is rotated 270 degrees clockwise.

  • VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR specifies th= at image content is mirrored horizontally.

  • VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR sp= ecifies that image content is mirrored horizontally, then rotated 90 degrees clockwise.

  • VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR specifies that image content is mirrored horizontally, then rotated 180 degrees clockwise.

  • VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR specifies that image content is mirrored horizontally, then rotated 270 degrees clockwise.

  • VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR specifies that the presentation transform is not specified, and is instead determined by platform-specific considerations and mechanisms outside Vulkan.

typedef VkFlags VkSurfaceTransformFlagsKHR;

VkSurfaceTransformFlagsKHR is a bitmask type for setting a = mask of zero or more VkSurfaceTransformFlagBitsKHR.

typedef enum VkCompositeAlphaFl=
agBitsKHR {
    VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR =3D 0x00000001,
    VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR =3D 0x000=
00002,
    VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR =3D 0x00=
000004,
    VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR =3D 0x00000008,
} VkCompositeAlphaFlagBitsKHR;

These values are described as follows:

  • VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR: The alpha channel, if it exists, of the images is ignored in the compositing process. Instead, the image is treated as if it has a constant alpha of 1.0.

  • VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR: The alpha channe= l, if it exists, of the images is respected in the compositing process. The non-alpha channels of the image are expected to already be multiplied by the alpha channel by the application.

  • VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR: The alpha chann= el, if it exists, of the images is respected in the compositing process. The non-alpha channels of the image are not expected to already be multiplied by the alpha channel by the application; instead, the compositor will multiply the non-alpha channels of the image by the alpha channel during compositing.

  • VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR: The way in which the presentation engine treats the alpha channel in the images is unknown to the Vulkan API. Instead, the application is responsible for setting the composite alpha blending mode using native window system commands. If the application does not set the blending mode using native window system commands, then a platform-specific default will be used.

typedef VkFlags VkCompositeAlphaFlagsKHR;

VkCompositeAlphaFlagsKHR is a bitmask type for setting a ma= sk of zero or more VkCompositeAlphaFlagBitsKHR.

To query the supported swapchain format-color space pairs for a surface, call:

VkResult vkGetPhys=
icalDeviceSurfaceFormatsKHR(
    VkPhysicalDevice                            physicalDevice,
    VkSurfaceKHR                                surface,
    uint32_t*                                   pSurfaceFormatCount,
    VkSurfaceFormatKHR*                         pSurfaceFormats);
  • physicalDevice is the physical device that will be associat= ed with the swapchain to be created, as described for vkCreateSwapchainKHR.

  • surface is the surface that will be associated with the swa= pchain.

  • pSurfaceFormatCount is a pointer to an integer related to t= he number of format pairs available or queried, as described below.

  • pSurfaceFormats is either NULL or a pointer to= an array of VkSurfaceFormatKHR structures.

If pSurfaceFormats is NULL, then the number of= format pairs supported for the given surface is returned in pSurfaceFormatCount. The number of format pairs supported will be greater than or equal to 1. Otherwise, pSurfaceFormatCount must point to a variable set by the user to the number of elements in the pSurfaceFormats array, a= nd on return the variable is overwritten with the number of structures actually written to pSurfaceFormats. If the value of pSurfaceFormatCount is less than the number of= format pairs supported, at most pSurfaceFormatCount structures will b= e written. If pSurfaceFormatCount is smaller than the number of format pa= irs supported for the given surface, VK_INCOMPLETE wi= ll be returned instead of VK_SUCCESS to indicate that not all the available v= alues were returned.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • surface must be a valid <= code>VkSurfaceKHR handle

  • pSurfaceFormatCount mu= st be a valid pointer to a uint32_t value

  • If the value referenced by pSurfaceFormatCount is n= ot 0, and pSurfaceFormats is not NULL, pSurfaceFormats must be a= valid pointer to an array of pSurfaceFormatCount VkSurf= aceFormatKHR structures

  • Bo= th of physicalDevice, and surface must have been created, allocated, or retrieved from t= he same VkInstance

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_SURFACE_LOST_KHR

The VkSurfaceFormatKHR structure is defined as:

typedef struct VkSurfaceFormatK=
HR {
    VkFormat           format;
    VkColorSpaceKHR    colorSpace;
} VkSurfaceFormatKHR;
  • format is a VkFormat that is compatible with = the specified surface.

  • colorSpace is a presentation VkColorSpaceK= HR that is compatible with the surface.

To query the supported swapchain format tuples for a surface, call:

VkResult vkGetPhys=
icalDeviceSurfaceFormats2KHR(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceSurfaceInfo2KHR*=
      pSurfaceInfo,
    uint32_t*                                   pSurfaceFormatCount,
    VkSurfaceFormat2KHR*                        pSurfaceFormats);
  • physicalDevice is the physical device that will be associat= ed with the swapchain to be created, as described for vkCreateSwapchainKHR.

  • pSurfaceInfo points to an instance of the VkPhysicalDeviceSurfaceInfo2KHR struct= ure, describing the surface and other fixed parameters that would be consumed by vkCreateSwapchainKHR.

  • pSurfaceFormatCount is a pointer to an integer related to t= he number of format tuples available or queried, as described below.

  • pSurfaceFormats is either NULL or a pointer to= an array of VkSurfaceFormat2KHR structures.

If pSurfaceFormats is NULL, then the number of= format tuples supported for the given surface is returned in pSurfaceFormatCount. The number of format tuples supported will be greater than or equal to 1. Otherwise, pSurfaceFormatCount must point to a variable set by the user to the number of elements in the pSurfaceFormats array, a= nd on return the variable is overwritten with the number of structures actually written to pSurfaceFormats. If the value of pSurfaceFormatCount is less than the number of= format tuples supported, at most pSurfaceFormatCount structures will = be written. If pSurfaceFormatCount is smaller than the number of format tu= ples supported for the surface parameters described in pSurfaceInfo= , VK_INCOMPLETE will be returned instead of VK_SUCCESS to indicate that not all the available values were returned.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pSurfaceInfo must b= e a valid pointer to a valid VkPhysicalDeviceSurfaceInfo2KHR s= tructure

  • pSurfaceFormatCount m= ust be a valid pointer to a uint32_t value

  • If the value referenced by pSurfaceFormatCount is = not 0, and pSurfaceFormats is not NULL, pSurfaceFormats must be = a valid pointer to an array of pSurfaceFormatCount VkSur= faceFormat2KHR structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_SURFACE_LOST_KHR

The VkSurfaceFormat2KHR structure is defined as:

typedef struct VkSurfaceFormat2=
KHR {
    VkStructureType       sType;
    void*                 pNext;
    VkSurfaceFormatKHR    surfaceFormat;
} VkSurfaceFormat2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • surfaceFormat is an instance of VkSurfa= ceFormatKHR describing a format-color space pair that is compatible with the specified surface.

Valid Usage (Implicit)
  • sType <= strong class=3D"purple">must be VK_STRUCTURE_TYPE_SURFACE_FO= RMAT_2_KHR

  • pNext <= strong class=3D"purple">must be NULL

While the format of a presentable image refers to the encod= ing of each pixel, the colorSpace determines how the presentation engine interprets the pixel values. A color space in this document refers to a specific color space (defined by the chromaticities of its primaries and a white point in CIE Lab), and a transfer function that is applied before storing or transmitting color data in the given color space.

Possible values of VkSurfaceFormatKHR::col= orSpace, specifying supported color spaces of a presentation engine, are:

typedef enum VkColorSpaceKHR {
    VK_COLOR_SPACE_SRGB_NONLINEAR_KHR =3D 0,
    VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT =3D 100=
0104001,
    VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT =3D 100=
0104002,
    VK_COLOR_SPACE_DCI_P3_LINEAR_EXT =3D 1000104003=
,
    VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT =3D 1000104=
004,
    VK_COLOR_SPACE_BT709_LINEAR_EXT =3D 1000104005<=
/span>,
    VK_COLOR_SPACE_BT709_NONLINEAR_EXT =3D 10001040=
06,
    VK_COLOR_SPACE_BT2020_LINEAR_EXT =3D 1000104007=
,
    VK_COLOR_SPACE_HDR10_ST2084_EXT =3D 1000104008<=
/span>,
    VK_COLOR_SPACE_DOLBYVISION_EXT =3D 1000104009,
    VK_COLOR_SPACE_HDR10_HLG_EXT =3D 1000104010,
    VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT =3D 10001040=
11,
    VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT =3D 10001=
04012,
    VK_COLOR_SPACE_PASS_THROUGH_EXT =3D 1000104013<=
/span>,
    VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT =3D =
1000104014,
} VkColorSpaceKHR;
  • VK_COLOR_SPACE_SRGB_NONLINEAR_KHR specifies support for the= sRGB color space.

  • VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT specifies support f= or the Display-P3 color space and applies an sRGB-like transfer function (defined below).

  • VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT specifies support f= or the extended sRGB color space and applies a linear transfer function.

  • VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT specifies suppor= t for the extended sRGB color space and applies an sRGB transfer function.

  • VK_COLOR_SPACE_DCI_P3_LINEAR_EXT specifies support for the = DCI-P3 color space and applies a linear OETF.

  • VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT specifies support for t= he DCI-P3 color space and applies the Gamma 2.6 OETF.

  • VK_COLOR_SPACE_BT709_LINEAR_EXT specifies support for the B= T709 color space and applies a linear OETF.

  • VK_COLOR_SPACE_BT709_NONLINEAR_EXT specifies support for th= e BT709 color space and applies the SMPTE 170M OETF.

  • VK_COLOR_SPACE_BT2020_LINEAR_EXT specifies support for the = BT2020 color space and applies a linear OETF.

  • VK_COLOR_SPACE_HDR10_ST2084_EXT specifies support for the H= DR10 (BT2020 color) space and applies the SMPTE ST2084 Perceptual Quantizer (PQ) OETF.

  • VK_COLOR_SPACE_DOLBYVISION_EXT specifies support for the Do= lby Vision (BT2020 color space), proprietary encoding, and applies the SMPTE ST2084 OETF.

  • VK_COLOR_SPACE_HDR10_HLG_EXT specifies support for the HDR1= 0 (BT2020 color space) and applies the Hybrid Log Gamma (HLG) OETF.

  • VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT specifies support for th= e AdobeRGB color space and applies a linear OETF.

  • VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT specifies support for= the AdobeRGB color space and applies the Gamma 2.2 OETF.

  • VK_COLOR_SPACE_PASS_THROUGH_EXT specifies that color compon= ents are used =E2=80=9Cas is=E2=80=9D. This is intended to allow applications to supply data for color spaces not described here.

The color components of Non-linear color space swap chain images have ha= d the appropriate transfer function applied. Vulkan requires that all implementations support the sRGB transfer function when using an SRGB pixel format. Other transfer functions, such as SMPTE 170M or SMPTE2084, must not be performed by the implementation, but can = be performed by the application shader. This extension defines enums for VkColorSpaceKHR that = correspond to the following color spaces:

Table 43. Color Spaces and Attributes
Name Red Primary Green Primary Blue Primary White-point Transfer function

DCI= -P3

0.6= 80, 0.320

0.2= 65, 0.690

0.1= 50, 0.060

0.3= 127, 0.3290 (D65)

Gam= ma 2.6

Dis= play-P3

0.6= 80, 0.320

0.2= 65, 0.690

0.1= 50, 0.060

0.3= 127, 0.3290 (D65)

Dis= play-P3

BT7= 09

0.6= 40, 0.330

0.3= 00, 0.600

0.1= 50, 0.060

0.3= 127, 0.3290 (D65)

SMP= TE 170M

sRG= B

0.6= 40, 0.330

0.3= 00, 0.600

0.1= 50, 0.060

0.3= 127, 0.3290 (D65)

sRG= B

ext= ended sRGB

0.6= 40, 0.330

0.3= 00, 0.600

0.1= 50, 0.060

0.3= 127, 0.3290 (D65)

ext= ended sRGB

HDR= 10_ST2084

0.7= 08, 0.292

0.1= 70, 0.797

0.1= 31, 0.046

0.3= 127, 0.3290 (D65)

ST2= 084

DOL= BYVISION

0.7= 08, 0.292

0.1= 70, 0.797

0.1= 31, 0.046

0.3= 127, 0.3290 (D65)

ST2= 084

HDR= 10_HLG

0.7= 08, 0.292

0.1= 70, 0.797

0.1= 31, 0.046

0.3= 127, 0.3290 (D65)

HLG=

Ado= beRGB

0.6= 40, 0.330

0.2= 10, 0.710

0.1= 50, 0.060

0.3= 127, 0.3290 (D65)

Ado= beRGB

For Opto-Electrical Transfer Function (OETF), unless otherwise specified= , the values of L and E a= re defined as:

L - linear luminance of image \(0 \leq L \leq = 1\) for conventional colorimetry

E - corresponding electrical signal (value sto= red in memory)

30.5.1. sRGB transfer function

\[\begin{aligned} E & =3D \begin{cases} 1.055 \times L^{1 \over 2.4} - 0.055 & \text{for}\ 0.0031308 \leq = L \leq 1 \\ 12.92 \times L & \text{for}\ 0 \leq L < 0= .0031308 \end{cases} \end{aligned}\]

30.5.2. Display-P3 EOTF

\[\begin{aligned} E & =3D \begin{cases} (a \times L + b)^{2.4} & \text{for}\ 0.039 \leq L \leq 1 \\ b \times L & \text{for}\ 0 \leq L < 0.039 \end{cases} \end{aligned}\]

\(a =3D 0.948\)
\(b =3D 0.052\)
\(c =3D 0.077\)

30.5.3. Display-P3 OETF

\[\begin{aligned} E & =3D \begin{cases} 1.055 \times L^{1 \over 2.4} - 0.055 & \text{for}\ 0.0030186 \leq = L \leq 1 \\ 12.92 \times L & \text{for}\ 0 \leq L < 0= .0030186 \end{cases} \end{aligned}\]
Note

For most uses, the sRGB OETF is equivalent.

30.5.4. Extended sRGB OETF

\[\begin{aligned} E & =3D \begin{cases} 1.055 \times L^{1 \over 2.4} - 0.055 & \text{for}\ 0.0031308 \leq = L \leq 7.5913 \\ 12.92 \times L & \text{for}\ 0 \leq L < 0= .0031308 \\ -f(-L) & \text{for}\ L < 0 \end{cases} \end{aligned}\]

L - luminance of image is within [-0.6038, 7.5913].

E can be negative and/or > 1. That is how extended sRGB specifies colors outside the standard sRGB gamut. This means extended sRGB needs a floating point pixel format to cover the intended color range.

30.5.5. SMPTE 170M OETF

\[\begin{aligned} E & =3D \begin{cases} \alpha \times L^{0.45} - (1 - \alpha) & \text{for}\ \beta \leq L \= leq 1 \\ 4.5 \times L & \text{for}\ 0 \leq L <= ; \beta \end{cases} \end{aligned}\]

\(\alpha =3D 1.099 \text{ and } \beta =3D 0.018 \text{ for 10-bits and less per sample system (the values given in Rec. 709)}\)
\(\alpha =3D 1.0993 \text{ and } \beta =3D 0.0181 \text{ for 12-bits per sample system}\)

30.5.6. SMPTE ST2084 OETF (Inver= se-EOTF)

\[ E =3D (\frac{c_1 + c_2 \times L^{m_1}}{1 + c_3 \times L^{m_1}})^{m_2} \]

where:

\(m_1 =3D 2610 / 4096 \times \frac{1}{4} =3D 0.1593017578125\)
\(m_2 =3D 2523 / 4096 \times 128 =3D 78.84375\)
\(c_1 =3D 3424 / 4096 =3D 0.8359375 =3D c3 - c2 + 1\)
\(c_2 =3D 2413 / 4096 \times 32 =3D 18.8515625\)
\(c_3 =3D 2392 / 4096 \times 32 =3D 18.6875\)

30.5.7. Hybrid Log Gamma (HLG)

\[\begin{aligned} E & =3D \begin{cases} r \sqrt{L} & \text{for}\ 0 \leq L \leq 1 \\ a \times \ln(L - b) + c & \text{for}\ 1 < L \end{cases} \end{aligned}\]

L=E2=80=89=E2=80=94=E2=80=89is the si= gnal normalized by the reference white level
r=E2=80=89=E2=80=94=E2=80=89is the refer= ence white level and has a signal value of 0.5
a =3D 0.17883277 and = b =3D 0.28466892 and c =3D 0.55= 991073

30.5.8. Adobe RGB (1998) OETF

\(E =3D L^\frac{1}{2.19921875}\)

30.5.9. Gamma 2.6 OETF

\(E =3D L^\frac{1}{2.6}\)

An implementation supporting this extension indicates support for these color spaces via VkSurfaceFormatKHR structures retu= rned from vkGetPhysicalDeviceSurfaceFormatsKHR<= /a>.

Vulkan requires that all implementations support the sRGB Opto-Electrica= l Transfer Function (OETF) and Electro-optical transfer function (EOTF) when using an SRGB pixel format. Other transfer functions, such as SMPTE 170M, must= not be performed by the implementation, but can be performed by t= he application shader.

If pSurfaceFormats includes an entry whose value for = colorSpace is VK_COLOR_SPACE_SRGB_NONLINEAR_KHR and whose value for format is a UNORM (or SRGB) format and the corresponding SRGB (or UNORM) format is a color renderable format for VK_IMAGE_TILING_OPTIMAL, then pSurfaceFormats must also co= ntain an entry with the same value for colorSpace and format equal to the corresponding = SRGB (or UNORM) format.

Note

If pSurfaceFormats includes just one entry, whose value for format is VK_FORMAT_UNDEFINED, surface has no preferred format. In this case, the application can use any= valid VkFormat value.

Note

In the initial release of the VK_KHR_surface and VK_KHR_swapchain extensions, the token VK_COLORSPACE_SRGB_NONLINEAR_KHR was use= d. Starting in the 2016-05-13 updates to the extension branches, matching release 1.0.13 of the core API specification, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR is used instead for consiste= ncy with Vulkan naming rules. The older enum is still available for backwards compatibility.

To query the supported presentation modes for a surface, call:

VkResult vkGetPhys=
icalDeviceSurfacePresentModesKHR(
    VkPhysicalDevice                            physicalDevice,
    VkSurfaceKHR                                surface,
    uint32_t*                                   pPresentModeCount,
    VkPresentModeKHR*                           pPresentModes);
  • physicalDevice is the physical device that will be associat= ed with the swapchain to be created, as described for vkCreateSwapchainKHR.

  • surface is the surface that will be associated with the swa= pchain.

  • pPresentModeCount is a pointer to an integer related to the= number of presentation modes available or queried, as described below.

  • pPresentModes is either NULL or a pointer to a= n array of VkPresentModeKHR values, indicating the supported pre= sentation modes.

If pPresentModes is NULL, then the number of p= resentation modes supported for the given surface is returned in pPresentModeCount. Otherwise, pPresentModeCount must point to a variable set by the user to the number of elements in the pPresentModes array, and on r= eturn the variable is overwritten with the number of values actually written to pPresentModes. If the value of pPresentModeCount is less than the number of presentation modes supported, at most pPresentModeCount values= will be written. If pPresentModeCount is smaller than the number of presentatio= n modes supported for the given surface, VK_INCOMPLETE wi= ll be returned instead of VK_SUCCESS to indicate that not all the available v= alues were returned.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_SURFACE_LOST_KHR

Possible values of elements of the vkGetPhysicalDeviceSurfacePresen= tModesKHR::pPresentModes array, indicating the supported presentation modes for a surface, are:

typedef enum VkPresentModeKHR {
    VK_PRESENT_MODE_IMMEDIATE_KHR =3D 0,
    VK_PRESENT_MODE_MAILBOX_KHR =3D 1,
    VK_PRESENT_MODE_FIFO_KHR =3D 2,
    VK_PRESENT_MODE_FIFO_RELAXED_KHR =3D 3,
    VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR =3D 1=
000111000,
    VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR =3D 1000111001,
} VkPresentModeKHR;
  • VK_PRESENT_MODE_IMMEDIATE_KHR specifies that the presentati= on engine does not wait for a vertical blanking period to update the current image, meaning this mode may resu= lt in visible tearing. No internal queuing of presentation requests is needed, as the requests are applied immediately.

  • VK_PRESENT_MODE_MAILBOX_KHR specifies that the presentation= engine waits for the next vertical blanking period to update the current image. Tearing cannot be observed. An internal single-entry queue is used to hold pending presentation requests. If the queue is full when a new presentation request is received, the new request replaces the existing entry, and any images associated with the prior entry become available for re-use by the application. One request is removed from the queue and processed during each vertical blanking period in which the queue is non-empty.

  • VK_PRESENT_MODE_FIFO_KHR specifies that the presentation en= gine waits for the next vertical blanking period to update the current image. Tearing cannot be observed. An internal queue is used to hold pending presentation requests. New requests are appended to the end of the queue, and one request is removed from the beginning of the queue and processed during each vertical blanking period in which the queue is non-empty. This is the only value of presentMode that is required to be supported.

  • VK_PRESENT_MODE_FIFO_RELAXED_KHR specifies that the present= ation engine generally waits for the next vertical blanking period to update the current image. If a vertical blanking period has already passed since the last update of the current image then the presentation engine does not wait for another vertical blanking period for the update, meaning this mode may result in visible tearing in this case. This mode is useful for reducing visual stutter with an application that will mostly present a new image before the next vertical blanking period, but may occasionally be late, and present a new image just after the next vertical blanking period. An internal queue is used to hold pending presentation requests. New requests are appended to the end of the queue, and one request is removed from the beginning of the queue and processed during or after each vertical blanking period in which the queue is non-empty.

  • VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR specifies that th= e presentation engine and application have concurrent access to a single image, which is referred to as a shared presentable image. The presentation engine is only required to update the current image after a new presentation request is received. Therefore the application must make a pre= sentation request whenever an update is required. However, the presentation engine may upda= te the current image at any point, meaning this mode may result in vi= sible tearing.

  • VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR specifies tha= t the presentation engine and application have concurrent access to a single image, which is referred to as a shared presentable image. The presentation engine periodically updates the current image on its regular refresh cycle. The application is only required to make one initial presentation request, after which the presentation engine must<= /strong> update the current image without any need for further presentation requests. The application can indicate the image co= ntents have been updated by making a presentation request, but this does not guarantee the timing of when it will be updated. This mode may result in visible tearing i= f rendering to the image is not timed correctly.

The supported VkImageUsageFlagBits of the pres= entable images of a swapchain created for a surface may diffe= r depending on the presentation mode, and can be determined as per the table below:

Table 44. Presentable image usage queries
Presentation mode Image usage flags

VK_PRESENT_MODE_IMMEDIATE_KHR

VkSurfaceCapabilitiesKHR::supportedUsageFl= ags

VK_PRESENT_MODE_MAILBOX_KHR

VkSurfaceCapabilitiesKHR::supportedUsageFl= ags

VK_PRESENT_MODE_FIFO_KHR

VkSurfaceCapabilitiesKHR::supportedUsageFl= ags

VK_PRESENT_MODE_FIFO_RELAXED_KHR

VkSurfaceCapabilitiesKHR::supportedUsageFl= ags

VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR

VkSharedPresentSurfaceCapabilitiesKHR::sharedPresentSupportedUsageFlags

VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR

VkSharedPresentSurfaceCapabilitiesKHR::sharedPresentSupportedUsageFlags

Note

For reference, the mode indicated by VK_PRESENT_MODE_FIFO_KHR is equivalent to the behavior of {wgl|glX|egl}SwapBuffers with a swap interval of 1, while the mode indicated by VK_PRESENT_MODE_FIFO_RELAXED_KHR is equivalent to the behavior of {wgl|glX}SwapBuffers with a swap interval of -1 (from the {WGL|GLX}_EXT_swap_control_tear extensions).

30.6. Device Group Queries

A logical device that represents multiple physical devices may support presenting from images on more than one physical device, or combining image= s from multiple physical devices.

To query these capabilities, call:

VkResult vkGetDevi=
ceGroupPresentCapabilitiesKHR(
    VkDevice                                    device,
    VkDeviceGroupPresentCapabilitiesKHR*        pDeviceGroupPresentCapabili=
ties);
  • device is the logical device.

  • pDeviceGroupPresentCapabilities is a pointer to a structure= of type VkDeviceGroupPresentCapabilitiesK= HR that is filled with the logical device=E2=80=99s capabilities.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDeviceGroupPresentCapabilitiesKHR structure is define= d as:

typedef struct VkDeviceGroupPre=
sentCapabilitiesKHR {
    VkStructureType                     sType;
    const void*                         pNext;
    uint32_t                            presentMask[VK_MAX_DEVICE_GROUP_SIZ=
E];
    VkDeviceGroupPresentModeFlagsKHR    modes;
} VkDeviceGroupPresentCapabilitiesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • presentMask is an array of masks, where the mask at element i is non-zero if physical device i has a presentation engine, and where bit j is set in element i if physical device i can pr= esent swapchain images from physical device j. If element i is non-zero, then bit i must be set.

  • modes is a bitmask of = VkDeviceGroupPresentModeFlagBitsKHR indicating which device group presentation modes are supported.

modes always has VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_B= IT_KHR set.

The present mode flags are also used when presenting an image, in VkDeviceGroupPresentInfoKHR::mode.

If a device group only includes a single physical device, then mod= es must equal VK_DEVICE_GROUP_PRESENT_= MODE_LOCAL_BIT_KHR.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR

  • pNext must be NULL<= /p>

Some surfaces may not be capable of us= ing all the device group present modes.

To query the supported device group present modes for a particular surfa= ce, call:

VkResult vkGetDevi=
ceGroupSurfacePresentModesKHR(
    VkDevice                                    device,
    VkSurfaceKHR                                surface,
    VkDeviceGroupPresentModeFlagsKHR*           pModes);
  • device is the logical device.

  • surface is the surface.

  • pModes is a pointer to a value of type VkDeviceGroupPresentModeFlagsKHR that is filled with the suppo= rted device group present modes for the surface.

The modes returned by this command are not invariant, and may change in response to the surface being moved, resized, or occluded. These modes must be a subset of the modes= returned by vkGetDeviceGroupPresentCapabilities= KHR.

Valid Usage (Implicit)
Host Synchronization
  • Host access to surface must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_SURFACE_LOST_KHR

When using VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR= , the application may need to know which re= gions of the surface are used when presenting locally on each physical device. Presentation of swapchain images to this surface need only have valid contents in the regions returned by this command.

To query a set of rectangles used in presentation on the physical device= , call:

VkResult vkGetPhys=
icalDevicePresentRectanglesKHR(
    VkPhysicalDevice                            physicalDevice,
    VkSurfaceKHR                                surface,
    uint32_t*                                   pRectCount,
    VkRect2D*                                   pRects);
  • physicalDevice is the physical device.

  • surface is the surface.

  • pRectCount is a pointer to an integer related to the number= of rectangles available or queried, as described below.

  • pRects is either NULL or a pointer to an array= of VkRect2D structures.

If pRects is NULL, then the number of rectangl= es used when presenting the given surface is returned in pRectCount. Otherwise, pRectCount must p= oint to a variable set by the user to the number of elements in the pRects array, and on return the vari= able is overwritten with the number of structures actually written to pRects<= /code>. If the value of pRectCount is less than the number of rectangl= es, at most pRectCount structures will be written. If pRectCount is smaller than the number of rectangles used fo= r the given surface, VK_INCOMPLETE will be returned ins= tead of VK_SUCCESS to indicate that not all the available values were returned.

The values returned by this command are not invariant, and may change in response to the surface being moved, resized, or occluded.

The rectangles returned by this command must not overlap.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • surface must be a vali= d VkSurfaceKHR handle

  • pRectCount must be = a valid pointer to a uint32_t value

  • = If the value referenced by pRectCount is not 0, and pRects is not NULL, pRects <= strong class=3D"purple">must be a valid pointer to an array of pRectCount VkRect2D structures

  • = Both of physicalDevice, and surface must have been created, allocated, or retrieved from = the same VkInstance

Host Synchronization
  • Host access to surface must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

30.7. Display Timing Queries

Traditional game and real-time-animation applications frequently use VK_PRESENT_MODE_FIFO_KHR so that presentable images are update= d during the vertical blanking period of a given refresh cycle (RC) of the presentation engine=E2=80=99s display. This avoids the visual anomaly known as tearing.

However, synchronizing the presentation of images with the RC does not prevent all forms of visual anomalies. Stuttering occurs when the geometry for each presentable image isn=E2=80=99= t accurately positioned for when that image will be displayed. The geometry may appear to move too little some RCs, and too much for others. Sometimes the animation appears to freeze, when the same image is used for more than one RC.

In order to minimize stuttering, an application needs to correctly posit= ion their geometry for when the presentable image will be displayed to the user= . To accomplish this, applications need various timing information about the presentation engine=E2=80=99s display. They need to know when presentable images were actually presented, and when they could have been presented. Applications also need to tell the presentation engine to display an image no sooner than a given time. This can allow the application=E2=80=99s animation to look smooth to the us= er, with no stuttering. The VK_GOOGLE_display_timing extension allows an application t= o satisfy these needs.

The presentation engine=E2=80=99s display typically refreshes the pixels= that are displayed to the user on a periodic basis. The period may be fixed or variable. In many cases, the presentation engine is associated with fixed refresh rat= e (FRR) display technology, with a fixed refresh rate (RR, e.g. 60Hz). In some cases, the presentation engine is associated with variable refresh rate (VRR) display technology, where each refresh cycle (RC) can vary in length. This extension treats VRR displays as if they are FRR.

To query the duration of a refresh cycle (RC) for the presentation engin= e=E2=80=99s display, call:

VkResult vkGetRefr=
eshCycleDurationGOOGLE(
    VkDevice                                    device,
    VkSwapchainKHR                              swapchain,
    VkRefreshCycleDurationGOOGLE*               pDisplayTimingProperties);<=
/code>
  • device is the device associated with swapchain= .

  • swapchain is the swapchain to obtain the refresh duration f= or.

  • pDisplayTimingProperties is a pointer to an instance of the VkRefreshCycleDurationGOOGLE structure.

Valid Usage (Implicit)
  • device must be a valid Vk= Device handle

  • = swapchain must be a valid VkSwapchainKHR handle

  • pDisplayTimingProperties must be a valid pointer to a VkRefreshCycleDurationGOOGLE= structure

  • Both of= device, and swapchain m= ust have been created, allocated, or retrieved from the same VkInstance

Host Synchronization
  • Host access to swapchain must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_SURFACE_LOST_KHR

The VkRefreshCycleDurationGOOGLE structure is defined as:

typedef struct VkRefreshCycleDu=
rationGOOGLE {
    uint64_t    refreshDuration;
} VkRefreshCycleDurationGOOGLE;
  • refreshDuration is the number of nanoseconds from the start= of one refresh cycle to the next.

Note

The rate at which an application renders and presents new images is know= n as the image present rate (IPR, aka frame rate). The inverse of IPR, or the duration between each image present, is the imag= e present duration (IPD). In order to provide a smooth, stutter-free animation, an application will want its IPD to be a multiple of refreshDuration. For example, if a display has a 60Hz refresh rate, refreshDuration will be a value in nanoseconds that is approximately equal to 16.67ms. In such a case, an application will want an IPD of 16.67ms (1X multiplier o= f refreshDuration), or 33.33ms (2X multiplier of refreshDu= ration), or 50.0ms (3X multiplier of refreshDuration), etc.

In order to determine a target IPD for a display (i.e. a multiple of refreshDuration), an application needs to determine when its i= mages are actually displayed. Let=E2=80=99s say that an application has an initial target IPD of 16.67ms = (1X multiplier of refreshDuration). It will therefore position the geometry of a new image 16.67ms later than the previous image. Let=E2=80=99s say that this application is running on slower hardware, so t= hat it actually takes 20ms to render each new image. This will create visual anomalies, because the images won=E2=80=99t be disp= layed to the user every 16.67ms, nor every 20ms. In this case, it is better for the application to adjust its target IPD to 33.33ms (i.e. a 2X multiplier of refreshDuration), and tell th= e presentation engine to not present images any sooner than every 33.33ms. This will allow the geometry to be correctly positioned for each presentabl= e image.

Adjustments to an application=E2=80=99s IPD may be needed because differ= ent views of an application=E2=80=99s geometry can take different amounts of time to ren= der. For example, looking at the sky may take less time to render than looking a= t multiple, complex items in a room. In general, it is good to not frequently change IPD, as that can cause visual anomalies. Adjustments to a larger IPD because of late images should happen quickly, but adjustments to a smaller IPD should only happen if the actualPresentTime and earliestPresentTime members= of the VkPastPresentationTimingGOOGLE structur= e are consistently different, and if presentMargin is consistently large, over multiple imag= es.

The implementation will maintain a limited amount of history of timing information about previous presents. Because of the asynchronous nature of the presentation engine, the timing information for a given vkQueuePresentKHR command wi= ll become available some time later. These time values can be asynchronously queried, and will be returned if available. All time values are in nanoseconds, relative to a monotonically-increasing clock (e.g. CLOCK_MONOTONIC (see clock_gettime(2)) on Android = and Linux).

To asynchronously query the presentation engine, for newly-available tim= ing information about one or more previous presents to a given swapchain, call:=

VkResult vkGetPast=
PresentationTimingGOOGLE(
    VkDevice                                    device,
    VkSwapchainKHR                              swapchain,
    uint32_t*                                   pPresentationTimingCount,
    VkPastPresentationTimingGOOGLE*             pPresentationTimings);
  • device is the device associated with swapchain= .

  • swapchain is the swapchain to obtain presentation timing information duration for.

  • pPresentationTimingCount is a pointer to an integer related= to the number of VkPastPresentationTimingGOOGLE structures to query, = as described below.

  • pPresentationTimings is either NULL or a point= er to an an array of VkPastPresentationTimingGOOGLE structures.

If pPresentationTimings is NULL, then the numb= er of newly-available timing records for the given swapchain is returned in pPresentationTimingCount. Otherwise, pPresentationTimingCount m= ust point to a variable set by the user to the number of elements in the pPresentationTimings= array, and on return the variable is overwritten with the number of structures actually written to pPresentationTimings. If the value of pPresentationTimingCount is less than the numb= er of newly-available timing records, at most pPresentationTimingCount structures will be written. If pPresentationTimingCount is smaller than the number of newly-available timing records for the given swapchain, VK_INCOMPLETE will be returned instead of VK_SUCCESS to indicate that not all the available values were returned.

Valid Usage (Implicit)
  • <= code>device must be a valid = VkDevice handle

  • swapchain must be a valid = VkSwapchainKHR handle

  • pPresentationTimingCount must be a valid pointer to a uint32_t value

  • If the value referenced by pPresentationTimingCount is not 0, and pPresentationTimings is not NULL, pPresentationTimings m= ust be a valid pointer to an array of pPresentationTimingCou= nt VkPastPresentationTimingGOOGLE structures

  • Both = of device, and swapchain must have been created, allocated, or retrieved from the same VkInstance

Host Synchronization
  • Host access to swapchain must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_OUT_OF_DATE_KHR

  • VK_ERROR_SURFACE_LOST_KHR

The VkPastPresentationTimingGOOGLE structure is defined as:=

typedef struct VkPastPresentati=
onTimingGOOGLE {
    uint32_t    presentID;
    uint64_t    desiredPresentTime;
    uint64_t    actualPresentTime;
    uint64_t    earliestPresentTime;
    uint64_t    presentMargin;
} VkPastPresentationTimingGOOGLE;
  • presentID is an application-provided value that was given t= o a previous vkQueuePresentKHR command via VkPresentTimeGOOGLE::presentID (see b= elow). It can be used to uniquely identify a pre= vious present with the vkQueuePresentKHR command.

  • desiredPresentTime is an application-provided value that wa= s given to a previous vkQueuePresentKHR command via VkPresentTimeGOOGLE::desiredPresentTime. If non-zero, it was used by the application to indicate that an image not be presented any sooner than desiredPresentTime.

  • actualPresentTime is the time when the image of the swapchain was actually displayed.

  • earliestPresentTime is the time when the image of the swapchain could have been displayed. This may differ from actualPresentT= ime if the application requested that the image be presented no sooner than VkPresentTimeGOOGLE::desiredPresentTime.

  • presentMargin is an indication of how early the vkQueuePresentKHR command was processed compared to how soon i= t needed to be processed, and still be presented at earliestPresentTime.

The results for a given swapchain and presentID are only returned once from vkGetPastPresentationTimingGOOGLE.

The application can use the VkPa= stPresentationTimingGOOGLE values to occasionally adjust its timing. For example, if actualPresentTime is later than expected (e.g.= one refreshDuration late), the application may increase its target= IPD to a higher multiple of refreshDuration (e.g. decrease its frame = rate from 60Hz to 30Hz). If actualPresentTime and earliestPresentTime are = consistently different, and if presentMargin is consistently large enough, = the application may decrease its target IPD to a smaller multiple of refreshDuration (e.g. increase its frame rate from 30Hz to 60H= z). If actualPresentTime and earliestPresentTime are = same, and if presentMargin is consistently high, the application may delay = the start of its input-render-present loop in order to decrease the latency between user input and the corresponding present (always leaving some margi= n in case a new image takes longer to render than the previous image). An application that desires its target IPD to always be the same as refreshDuration, can also adjust features until actualPresentTime is never late and presentMargin= is satisfactory.

The full VK_GOOGLE_display_timing extension semantics are d= escribed for swapchains created with VK_PRESENT_MODE_FIFO_KHR. For example, non-zero values of VkPresentTimeGOOGLE::desiredPresentTime must be honored, and vkGetPastPresentationTimingGOOGLE sho= uld return a VkPastPresentationTimingGOOGLE structure with valid values for= all images presented with vkQueuePresentKHR. The semantics for other present modes are as follows:

  • VK_PRESENT_MODE_IMMEDIATE_KHR. The presentation engine may ignore non-ze= ro values of VkPresentTimeGOOGLE::desiredPresentTime in favor = of presenting immediately. The value of VkPastPresentationTimingGOOGLE::earliestPresentTime must be the same as VkPastPresentationTimingGOOGLE::actualPresentTime= , which should be when the presentation engine di= splayed the image.

  • VK_PRESENT_MODE_MAILBOX_KHR. The intention of using this present mode with this extension is to handle cases where an image is presented late, and the next image is presented soon enough to replace it at the next vertical blanking period. For images that are displayed to the user, the value of VkPastPresentationTimingGOOGLE::actualPresentTime= must be when the image was displayed. For images that are not displayed to the user, vkGetPastPresentationTimingGOOGLE may= not return a VkPastPresentationTimingGOOGLE structure, or it may return return a VkPastPresentationTimingGOOGLE structure with the value of z= ero for both VkPastPresentationTimingGOOGLE::actualPresentTi= me and VkPastPresentationTimingGOOGLE::earliestPresentTime<= /code>. It is possible that an application can su= bmit images with VkPresentTimeGOOGLE::desiredPresentTime values su= ch that new images may not be displayed. For example, if VkPresentTimeGOOGLE::desiredPresentTime<= /code> is far enough in the future that an image is not presented before vkQueuePresentKHR is called to present another image, the firs= t image will not be displayed to the user. If the application continues to do that, the presentation may not display new images.

  • VK_PRESENT_MODE_FIFO_RELAXED_KHR. For images that are presented in time to be displayed at the next vertical blanking period, the semantics are identical as for VK_PRESENT_MODE_FIFO_RELAXED_KHR. For images that are presented late, and are displayed after the start of the vertical blanking period (i.e. with tearing), the values of VkPastPresentationTimingGOOGLE may be treated as if the image was displayed at the start of the vertical blanking period, or may be treated the same as for VK_PRESENT_MODE_IMMEDIATE_KHR.

30.8. WSI Swapchain

A swapchain object (a.k.a. swapchain) provides the ability to present rendering results to a surface. Swapchain objects are represented by VkSwapchainKHR handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkSwapchainKHR)

A swapchain is an abstraction for an array of presentable images that ar= e associated with a surface. The presentable images are represented by VkImage objects crea= ted by the platform. One image (which can be an array image fo= r multiview/stereoscopic-3D surfaces) is displayed at a time, but multiple images can be queued for presentation. An application renders to the image, and then queues the image for presentation to the surface.

A native window cannot be associated w= ith more than one non-retired swapchain at a time. Further, swapchains cannot be created for= native windows that have a non-Vulkan graphics API surface associated with them.

Note

The presentation engine is an abstraction for the platform=E2=80=99s com= positor or display engine.

The presentation engine may be synchro= nous or asynchronous with respect to the application and/or logical device.

Some implementations may use the devic= e=E2=80=99s graphics queue or dedicated presentation hardware to perform presentation.

The presentable images of a swapchain are owned by the presentation engi= ne. An application can acquire use of a prese= ntable image from the presentation engine. Use of a presentable image must occur onl= y after the image is returned by vkAcquireNextImageKHR, and before it is presented by vkQueuePresentKHR. This includes transitioning the image layout and rendering commands.

An application can acquire use of a pr= esentable image with vkAcquireNextImageKHR. After acquiring a presentable image and before modifying it, the applicatio= n must use a synchronization primitive to e= nsure that the presentation engine has finished reading from the image. The application can then transition the i= mage=E2=80=99s layout, queue rendering commands to it, etc. Finally, the application presents the image with vkQueuePresentKHR, which releases the acquisition of the image.

The presentation engine controls the order in which presentable images a= re acquired for use by the application.

Note

This allows the platform to handle situations which require out-of-order return of images after presentation. At the same time, it allows the application to generate command buffers referencing all of the images in the swapchain at initialization time, rather than in its main loop.

How this all works is described below.

If a swapchain is created with presentMode set to either VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR or VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, a single presen= table image can be acquired, referred to as a s= hared presentable image. A shared presentable image may be concurr= ently accessed by the application and the presentation engine, without transitioning the image=E2=80=99s layo= ut after it is initially presented.

  • With VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, the present= ation engine is only required to update to the latest contents of a shared presentable image after a present. The application must call vkQueuePr= esentKHR to guarantee an update. However, the presentation engine may upda= te from it at any time.

  • With VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, the presentation engine will automatically present the latest contents of a shared presentable image during every refresh cycle. The application is only required to make one initial call to vkQueuePresentKHR, after which the presentation engine will up= date from it without any need for further present calls. The application can indicate the image co= ntents have been updated by calling vkQueuePresentKHR, but this does not guarantee the tim= ing of when updates will occur.

The presentation engine may access a s= hared presentable image at any time after it is first presented. To avoid tearing, an application should c= oordinate access with the presentation engine. This requires presentation engine timing information through platform-specific mechanisms and ensuring that color attachment writes are made available during the portion of the presentation engine=E2=80=99s refr= esh cycle they are intended for.

Note

The VK_KHR_shared_presentable_image extension does not prov= ide functionality for determining the timing of the presentation engine=E2=80= =99s refresh cycles.

In order to query a swapchain=E2=80=99s status when rendering to a share= d presentable image, call:

VkResult vkGetSwap=
chainStatusKHR(
    VkDevice                                    device,
    VkSwapchainKHR                              swapchain);
  • device is the device associated with swapchain= .

  • swapchain is the swapchain to query.

Valid Usage (Implicit)
  • devic= e must be a valid VkDevice handle

  • sw= apchain must be a valid VkSw= apchainKHR handle

  • Both of d= evice, and swapchain must have been created, allocated, or retrieved from the same VkInsta= nce

Host Synchronization
  • Host access to swapchain must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

  • VK_SUBOPTIMAL_KHR

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_OUT_OF_DATE_KHR

  • VK_ERROR_SURFACE_LOST_KHR

The possible return values for vkGetSwapchainStatusKHR should be interpreted as follows:

  • VK_SUCCESS specifies the presentation engine is presenting = the contents of the shared presentable image, as per the swapchain=E2=80=99s VkPresentModeKHR.

  • VK_SUBOPTIMAL_KHR the swapchain no longer matches the surfa= ce properties exactly, but the presentation engine is presenting the contents of the shared presentable image, as per the swapchain=E2=80=99s VkPresentModeKHR.

  • VK_ERROR_OUT_OF_DATE_KHR the surface has changed in such a = way that it is no longer compatible with the swapchain.

  • VK_ERROR_SURFACE_LOST_KHR the surface is no longer availabl= e.

Note

The swapchain state may be cached by i= mplementations, so applications should regularly call vkGetSwapchai= nStatusKHR when using a swapchain with VkPresentModeKHR set to VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR.

To create a swapchain, call:

VkResult vkCreateS=
wapchainKHR(
    VkDevice                                    device,
    const VkSwapchainCreateInfoKHR*       =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSwapchainKHR*                             pSwapchain);
  • device is the device to create the swapchain for.

  • pCreateInfo is a pointer to an instance of the VkSwapchainCreateInfoKHR structure specifying= the parameters of the created swapchain.

  • pAllocator is the allocator used for host memory allocated = for the swapchain object when there is no more specific allocator available (see Memory Allocation).

  • pSwapchain is a pointer to a VkSwapchainKHR= handle in which the created swapchain object will be returned.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pCr= eateInfo must be a valid pointer t= o a valid VkSwapchainCreateInfoKHR structure

  • If p= Allocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloca= tionCallbacks structure

  • pSwa= pchain must be a valid pointer to = a VkSwapchainKHR handle

Host Synchronization
  • Host access to pCreateInfo.surface must be externally synchronized

  • Host access to pCreateInfo.oldSwapchain must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_SURFACE_LOST_KHR

  • VK_ERROR_NATIVE_WINDOW_IN_USE_KHR

The VkSwapchainCreateInfoKHR structure is defined as:

typedef struct VkSwapchainCreat=
eInfoKHR {
    VkStructureType                  sType;
    const void*                      pNext;
    VkSwapchainCreateFlagsKHR        flags;
    VkSurfaceKHR                     surface;
    uint32_t                         minImageCount;
    VkFormat                         imageFormat;
    VkColorSpaceKHR                  imageColorSpace;
    VkExtent2D                       imageExtent;
    uint32_t                         imageArrayLayers;
    VkImageUsageFlags                imageUsage;
    VkSharingMode                    imageSharingMode;
    uint32_t                         queueFamilyIndexCount;
    const uint32_t*                  pQueu=
eFamilyIndices;
    VkSurfaceTransformFlagBitsKHR    preTransform;
    VkCompositeAlphaFlagBitsKHR      compositeAlpha;
    VkPresentModeKHR                 presentMode;
    VkBool32                         clipped;
    VkSwapchainKHR                   oldSwapchain;
} VkSwapchainCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkSwapc= hainCreateFlagBitsKHR indicating parameters of the swapchain creation.

  • surface is the surface onto which the swapchain will presen= t images. If the creation succeeds, the swapchain becomes associated with surface.

  • minImageCount is the minimum number of presentable images t= hat the application needs. The implementation will either create the swapchain with at least that many images, or it will fail to create the swapchain.

  • imageFormat is a VkFormat value specifying th= e format the swapchain image(s) will be created with.

  • imageColorSpace is a VkColorSpaceKHR v= alue specifying the way the swapchain interprets image data.

  • imageExtent is the size (in pixels) of the swapchain image(= s). The behavior is platform-dependent if the image extent does not match the surface=E2=80=99s currentExtent as returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR.

Note

On some platforms, it is normal that maxImageExtent may become (0, 0), for example when the window is minimized. In such a case, it is not possible to create a swapchain due to the Valid Usage requirements.

  • imageArrayLayers is the number of views in a multiview/ster= eo surface. For non-stereoscopic-3D applications, this value is 1.

  • imageUsage is a bitmask of VkImageUsa= geFlagBits describing the intended usage of the (acquired) swapchain images.

  • imageSharingMode is the sharing mode used for the image(s) = of the swapchain.

  • queueFamilyIndexCount is the number of queue families havin= g access to the image(s) of the swapchain when imageSharingMode = is VK_SHARING_MODE_CONCURRENT.

  • pQueueFamilyIndices is an array of queue family indices hav= ing access to the images(s) of the swapchain when imageSharingMode= is VK_SHARING_MODE_CONCURRENT.

  • preTransform is a VkSurfaceT= ransformFlagBitsKHR value describing the transform, relative to the presentation engine=E2=80=99s nat= ural orientation, applied to the image content prior to presentation. If it does not match the currentTransform value returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR, the presentation en= gine will transform the image content as part of the presentation operation.

  • compositeAlpha is a VkComposit= eAlphaFlagBitsKHR value indicating the alpha compositing mode to use when this surface is composited together with other surfaces on certain window systems.

  • presentMode is the presentation mode the swapchain will use= . A swapchain=E2=80=99s present mode determines how incoming present requests= will be processed and queued internally.

  • clipped specifies whether the Vulkan implementation is allo= wed to discard rendering operations that affect regions of the surface that are not visible.

    • If set to VK_TRUE, the presentable images associated with t= he swapchain may not own all of their pixels= . Pixels in the presentable images that correspond to regions of the target surface obscured by another window on the desktop, or subject to some other clipping mechanism will have undefined content when read back. Pixel shaders may not execute for these p= ixels, and thus any side effects they would have had will not occur. VK_TRUE value does not guarantee any clipping will occur, but allows more optimal presentation methods to be used on some platforms.

    • If set to VK_FALSE, presentable images associated with the swapchain will own all of the pixels they contain.

Note

Applications should set this value to = VK_TRUE if they do not expect to read back the content of presentable images before presenting them or after reacquiring them, and if their pixel shaders do not have any side effects that require them to run for all pixels in the presentable image.

  • oldSwapchain is VK_NULL_HANDLE, or the = existing non-retired swapchain currently associated with surface. Providing a valid oldSwapchain may aid in the resource reuse, and also allows the application to still present any images that are already acquired from it.

Upon calling vkCreateSwapchainKHR with an oldSwapchai= n that is not VK_NULL_HANDLE, oldSwapchain is retire= d=E2=80=89=E2=80=94=E2=80=89even if creation of the new swapchain fails. The new swapchain is created in the non-retired state whether or not oldSwapchain is VK_NULL_HANDLE.

Upon calling vkCreateSwapchainKHR with an oldSwapchai= n that is not VK_NULL_HANDLE, any images from oldSwapchain<= /code> that are not acquired by the application may be freed = by the implementation, which may occur even if creation of the new swapchain fails. The application can destroy oldSwap= chain to free all memory associated with oldSwapchain.

Note

Multiple retired swapchains can be ass= ociated with the same VkSurfaceKHR through multiple uses of oldSwapchain that outnumber calls to vkDestroySwapchainKHR.

After oldSwapchain is retired, the application can pass to vkQueuePresentKHR any images it had already acquired= from oldSwapchain. E.g., an application may present an image from the old swapchain before an image from the new swapchain is ready to be presented. As usual, vkQueuePresentKHR may fail if oldSwapchain has entered a state that causes VK_ERROR_OUT_OF_DATE_KHR to be ret= urned.

The application can continue to use a = shared presentable image obtained from oldSwapchain until a presentable image is acquired from t= he new swapchain, as long as it has not entered a state that causes it to return VK_ERROR_OUT_OF_DATE_KHR.

Valid Usage
  • surface must be a surface th= at is supported by the device as determined using vkGetPhysicalDeviceSurfaceSupportKHR

  • minImageCount must be greate= r than or equal to the value returned in the minImageCount member of the VkSurfaceCapabilities= KHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface

  • minImageCount must be less t= han or equal to the value returned in the maxImageCount member of the VkSurfaceCapabilitiesKHR= structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface if the returned maxImageCount is not zero

  • minImageCount must be = 1 if presentMode is either VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR or VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR

  • imageFormat and imageColorSpace must match the format and colorSpace members, respectively, of one of the VkSurfaceFormatKHR structures returned by vkGetPhysicalDeviceSurfaceFormatsKHR for the surface

  • imageExtent must be between = minImageExtent and maxImageExtent, inclusive, where minImageExtent a= nd maxImageExtent are members of the VkSurfaceCapabilitiesK= HR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface

  • imageExtent members width and height= must both be non-zero

  • imageArrayLayers must be gre= ater than 0 and less than or equal to the maxImageArrayLayers member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface

  • If presentMode is VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR or VK_PRESENT_MODE_FIFO_RELAXED_KHR, imageUsage must be a subset of the supported usage flags present in the supportedUsageFlags member of the Vk= SurfaceCapabilitiesKHR structure returned by vkGetPhysi= calDeviceSurfaceCapabilitiesKHR for surface

  • If presentMode is VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_= KHR or VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, imageU= sage must be a subset of the supported usage f= lags present in the sharedPresentSupportedUsageFlags member of the VkSharedPresentSurfaceCapabilitiesKH= R structure returned by vkGetPhysicalDeviceSurfaceCapab= ilities2KHR for surface

  • If imageSharingMode is VK_SHARING_MODE_CONCURRENT= , pQueueFamilyIndices must be = a valid pointer to an array of queueFamilyIndexCount uint32_t values

  • If imageSharingMode is VK_SHARING_MODE_CONCURRENT= , queueFamilyIndexCount must b= e greater than 1

  • If imageSharingMode is VK_SHARING_MODE_CONCURRENT= , each element of pQueueFamilyIndices must be unique and must be less than pQueueFamilyPropertyCount returned by either vkGetPhysicalDeviceQueueFamilyPro= perties or vkGetPhysicalDeviceQueueFamilyPr= operties2 for the physicalDevice that was used to create device

  • preTransform must be one of = the bits present in the supportedTransforms member of the VkSurfaceCapabilitiesK= HR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface

  • compositeAlpha must be one o= f the bits present in the supportedCompositeAlpha member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface

  • presentMode must be one of t= he VkPresentModeKHR values returned by vkGetPhysicalDeviceSurfacePresentModesKHR for the surface

  • If the logical device was created with VkDeviceGroupDeviceCreateInfo::phy= sicalDeviceCount equal to 1, flags must not contain VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR

  • If oldSwapchain is not VK_NULL_HANDLE, oldSwapchain must be a non-retired swapchain associate= d with native window referred to by surface

  • imageFormat, imageUsage, imageExtent= , and imageArrayLayers must be sup= ported for VK_IMAGE_TYPE_2D VK_IMAGE_TILING_OPTIMAL images as reported by vkGetPhysicalDeviceImageFormatPro= perties.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_SWAPC= HAIN_CREATE_INFO_KHR

  • Each pNex= t member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkDeviceGroupSwapchainCreateInfoKHR or Each sTy= pe member in the pNext chain m= ust be unique

  • flags= must be a valid combination of VkSwapchainCreateFlagBitsKHR values

  • sur= face must be a valid VkSurfa= ceKHR handle

  • imageFormat must be a valid VkFormat value

  • <= code>imageColorSpace must be a val= id VkColorSpaceKHR value

  • = imageUsage must be a valid combina= tion of VkImageUsageFlagBits values

  • = imageUsage must not be 0

  • = imageSharingMode must be a v= alid VkSharingMode value

  • preTransform must be a valid VkSurfaceTransformFlagBitsKHR value

  • compositeAlpha must be a valid= VkCompositeAlphaFlagBitsKHR value

  • presentMode must be a valid VkPresentModeKHR value

  • If <= code>oldSwapchain is not VK_NULL_HANDLE, o= ldSwapchain must be a valid = VkSwapchainKHR handle

  • If oldSwapchain is a valid handle, it must have been created, allocated, or retrieved from surface

  • Both of = oldSwapchain, and surface that are valid handles must have been created, allocated, or retrieved= from the same VkInstance

Bits which can be set in VkSwapchainCreateInfoKHR::flags, specifying parameters of swapchain creation, are:

typedef enum VkSwapchainCreateF=
lagBitsKHR {
    VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR =3D 0x00000001,
    VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR =3D 0x0000000=
2,
} VkSwapchainCreateFlagBitsKHR;
  • VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR spe= cifies that images created from the swapchain (i.e. with the swapchain member of VkImageSwapchainCreateInfoKHR = set to this swapchain=E2=80=99s handle) must use VK_IMAGE_CREATE_SP= LIT_INSTANCE_BIND_REGIONS_BIT.

  • VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR specifies that images created from the swapchain are protected images.

typedef VkFlags VkSwapchainCreateFlagsKHR;

VkSwapchainCreateFlagsKHR is a bitmask type for setting a m= ask of zero or more VkSwapchainCreateFlagBitsKHR.

If the pNext chain of VkSwapchain= CreateInfoKHR includes a VkDeviceGroupSwapchainCreateInfoKHR structure, then that struc= ture includes a set of device group present modes that the swapchain can be used with.

The VkDeviceGroupSwapchainCreateInfoKHR structure is define= d as:

typedef struct VkDeviceGroupSwa=
pchainCreateInfoKHR {
    VkStructureType                     sType;
    const void*                         pNext;
    VkDeviceGroupPresentModeFlagsKHR    modes;
} VkDeviceGroupSwapchainCreateInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • modes is a bitfield of modes that the swapchain can be used with.

If this structure is not present, modes is considered to be VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR.

Valid Usage (Implicit)

To enable surface counters when creating a swapchain, add VkSwapchainCounterCreateInfoEXT to the pNext chai= n of VkSwapchainCreateInfoKHR. VkSwapchainCounterCreateInfoEXT is defined as:

typedef struct VkSwapchainCount=
erCreateInfoEXT {
    VkStructureType             sType;
    const void*                 pNext;
    VkSurfaceCounterFlagsEXT    surfaceCounters;
} VkSwapchainCounterCreateInfoEXT;
Valid Usage (Implicit)
  • sT= ype must be VK_STRUCTURE_TYP= E_SWAPCHAIN_COUNTER_CREATE_INFO_EXT

  • surfaceCounters must b= e a valid combination of VkSurfaceCounterFlagB= itsEXT values

The requested counters become active when the first presentation command= for the associated swapchain is processed by the presentation engine. To query the value of an active counter, use:

VkResult vkGetSwap=
chainCounterEXT(
    VkDevice                                    device,
    VkSwapchainKHR                              swapchain,
    VkSurfaceCounterFlagBitsEXT                 counter,
    uint64_t*                                   pCounterValue);
  • device is the VkDevice associated with = swapchain.

  • swapchain is the swapchain from which to query the counter = value.

  • counter is the counter to query.

  • pCounterValue will return the current value of the counter.=

If a counter is not available because the swapchain is out of date, the implementation may return VK_ERROR_= OUT_OF_DATE_KHR.

Valid Usage
  • One or more present commands on swapchain must have been processed by the presentation engine.

Valid Usage (Implicit)
  • devi= ce must be a valid VkDevice<= /code> handle

  • s= wapchain must be a valid VkS= wapchainKHR handle

  • cou= nter must be a valid VkSurfaceCounterFlagBitsEXT value

  • pCounterValue must be a valid p= ointer to a uint64_t value

  • Both of = device, and swapchain must have been created, allocated, or retrieved from the same VkInst= ance

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_OUT_OF_DATE_KHR

As mentioned above, if vkCreateSwapchainKHR succeeds, it wi= ll return a handle to a swapchain that contains an array of at least minImageCoun= t presentable images.

While acquired by the application, presentable images can be used in any way that equivalent non-presentable images can be used. A presentable image is equivalent to a non-presentable image created with the following VkImageCreateInfo parameters:

VkImageCreateInfo Field Value

flags

VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT is set if V= K_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR is set

VK_IMAGE_CREATE_PROTECTED_BIT is set i= f VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR is set

all other bits are unset

imageType

VK_IMAGE_TYPE_2D

format

pCreateInfo=E2=86=92imageFormat

extent

{pCreateInfo=E2=86=92imageExtent.width, pCreateInfo=E2=86=92imageExtent.= height, 1}

mipLevels

1

arrayLayers

pCreateInfo=E2=86=92imageArrayLayers

samples

VK_SAMPLE_COUNT_1_BIT

tiling

VK_IMAGE_TILING_OPTIMAL

usage

pCreateInfo=E2=86=92imageUsage

sharingMode

pCreateInfo=E2=86=92imageSharingMode

queueFamilyIndexCount

pCreateInfo=E2=86=92queueFamilyIndexCount

pQueueFamilyIndices

pCreateInfo=E2=86=92pQueueFamilyIndices

initialLayout

VK_IMAGE_LAYOUT_UNDEFINED

The surface must not be d= estroyed until after the swapchain is destroyed.

If oldSwapchain is VK_NULL_HANDLE, and = the native window referred to by surface is already associated with a Vulkan swa= pchain, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR mus= t be returned.

If the native window referred to by surface is already asso= ciated with a non-Vulkan graphics API surface, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR<= /code> must be returned.

The native window referred to by surface must not become associated with a non-Vulkan graphics API surface before all associated Vulkan swapchains have been destroyed.

Like core functions, several WSI functions, including vkCreateSwapchainKHR return VK_ERROR_DEVICE_LOST = if the logical device was lost. See Lost Device. As with most core objects, VkSwapchainKHR is a child of the de= vice and is affected by the lost state; it must be= destroyed before destroying the VkDevice. However, VkSurfaceKHR is not a child of any VkDevice and is not otherwise affected by the lost device. After successfully recreating a VkDevice, the same VkSur= faceKHR can be used to create a new VkSwapc= hainKHR, provided the previous one was destroyed.

Note

As mentioned in Lost Device, after a lost device event, the VkPhysicalDevice ma= y also be lost. If other VkPhysicalDevice are available, they can be used together with the same VkSurfaceKHR to create the new VkSwapchain= KHR, however the application must query the su= rface capabilities again, because they may differ on a per-physical device = basis.

To destroy a swapchain object call:

void vkDestroySwapchainKHR(
    VkDevice                                    device,
    VkSwapchainKHR                              swapchain,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the VkDevice associated with = swapchain.

  • swapchain is the swapchain to destroy.

  • pAllocator is the allocator used for host memory allocated = for the swapchain object when there is no more specific allocator available (see Memory Allocation).

The application must not destroy a swa= pchain until after completion of all outstanding operations on images that were acquired from the swapchain. swapchain and all associated VkImage handles are = destroyed, and must not be acquired or used any more by = the application. The memory of each VkImage will only be freed after that image= is no longer used by the presentation engine. For example, if one image of the swapchain is being displayed in a window, the memory for that image may not be free= d until the window is destroyed, or another swapchain is created for the window. Destroying the swapchain does not invalidate the parent VkSurfaceKHR<= /code>, and a new swapchain can be created with i= t.

When a swapchain associated with a display surface is destroyed, if the image most recently presented to the display surface is from the swapchain being destroyed, then either any display resources modified by presenting images from any swapchain associated with the display surface must be reverted by the implementation to their state prior to the first present performed on one of these swapchains, or such resources must be left in their current state.

Valid Usage
  • All uses of presentable images acquired from swapchain must have completed execution

  • If VkAllocationCallbacks were provided when swapchain was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when swapchain= was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • device<= /code> must be a valid VkDevice handle

  • If s= wapchain is not VK_NULL_HANDLE, swapchain<= /code> must be a valid VkSwapchainK= HR handle

  • If = pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAlloc= ationCallbacks structure

  • Both of dev= ice, and swapchain that are valid handles must have been created, allocated, or retrieved from t= he same VkInstance

Host Synchronization
  • Host access to swapchain must be externally synchronized

When the VK_KHR_display_swapchain extension is enabled, mul= tiple swapchains that share presentable images are created by calling:

VkResult vkCreateS=
haredSwapchainsKHR(
    VkDevice                                    device,
    uint32_t                                    swapchainCount,
    const VkSwapchainCreateInfoKHR*       =
      pCreateInfos,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkSwapchainKHR*                             pSwapchains);
  • device is the device to create the swapchains for.

  • swapchainCount is the number of swapchains to create.

  • pCreateInfos is a pointer to an array of VkSwapchainCreateInfoKHR structures specifyin= g the parameters of the created swapchains.

  • pAllocator is the allocator used for host memory allocated = for the swapchain objects when there is no more specific allocator available (see Memory Allocation).

  • pSwapchains is a pointer to an array of VkS= wapchainKHR handles in which the created swapchain objects will be returned.

Valid Usage (Implicit)
  • d= evice must be a valid VkDevi= ce handle

  • <= code>pCreateInfos must be a valid = pointer to an array of swapchainCount valid VkSwapchainC= reateInfoKHR structures

  • If = pAllocator is not NULL, pAllocator <= strong class=3D"purple">must be a valid pointer to a valid V= kAllocationCallbacks structure

  • pSwapchains must be a valid po= inter to an array of swapchainCount VkSwapchainKHR handles

  • swapchainCount must be gr= eater than 0

Host Synchronization
  • Host access to pCreateInfos[].surface must be externally synchronized

  • Host access to pCreateInfos[].oldSwapchain must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INCOMPATIBLE_DISPLAY_KHR

  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_SURFACE_LOST_KHR

To obtain the array of presentable images associated with a swapchain, c= all:

VkResult vkGetSwap=
chainImagesKHR(
    VkDevice                                    device,
    VkSwapchainKHR                              swapchain,
    uint32_t*                                   pSwapchainImageCount,
    VkImage*                                    pSwapchainImages);
  • device is the device associated with swapchain= .

  • swapchain is the swapchain to query.

  • pSwapchainImageCount is a pointer to an integer related to = the number of presentable images available or queried, as described below.

  • pSwapchainImages is either NULL or a pointer t= o an array of VkImage handles.

If pSwapchainImages is NULL, then the number o= f presentable images for swapchain is returned in pSwapchainImageCount= . Otherwise, pSwapchainImageCount must<= /strong> point to a variable set by the user to the number of elements in the pSwapchainImages array, = and on return the variable is overwritten with the number of structures actually written to pSwapchainImages. If the value of pSwapchainImageCount is less than the number o= f presentable images for swapchain, at most pSwapchainImag= eCount structures will be written. If pSwapchainImageCount is smaller than the number of presenta= ble images for swapchain, VK_INCOMPLETE will be retur= ned instead of VK_SUCCESS to indicate that not all the available values were returned.

Valid Usage (Implicit)
  • devic= e must be a valid VkDevice handle

  • sw= apchain must be a valid VkSw= apchainKHR handle

  • pSwapchainImageCount must= be a valid pointer to a uint32_t value

  • I= f the value referenced by pSwapchainImageCount is not 0<= /code>, and pSwapchainImages is not NULL, p= SwapchainImages must be a valid po= inter to an array of pSwapchainImageCount VkImage= handles

  • Both of d= evice, and swapchain must have been created, allocated, or retrieved from the same VkInsta= nce

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Note

By knowing all presentable images used in the swapchain, the application can create command buffers that reference= these images prior to entering its main rendering loop.

The implementation will have already allocated and bound the memory back= ing the VkImages returned by vkGetSwapchainImagesKHR. The memory for each image will not alias with the memory for other images o= r with any VkDeviceMemory object. As such, performing any operation affecting the binding of memory to a presentable image results in undefined behavior. All presentable images are initially in the VK_IMAGE_LAYOUT_UNDEFINED= layout, thus before using presentable images, the application must transition them to a valid layout for the intended use.

Further, the lifetime of presentable images is controlled by the implementation so destroying a presentable image with vkDes= troyImage results in undefined behavior. See vkDestroySwapchainKHR for further details on= the lifetime of presentable images.

Images can also be created by using vkCreateImage with VkImageSwapchainCreateInfoKHR and bound = to swapchain memory using vkBindImageMemory2KHR with VkBindImageMemorySwapchainInfoKHR. These images can be used anywhere swapcha= in images are used, and are useful in logical devices with multiple physical devices to create peer memory bindings of swapchain memory. These images and bindings have no effect on what memory is presented. Unlike images retrieved from vkGetSwapchainImagesKHR, these im= ages must be destroyed with vk= DestroyImage.

To acquire an available presentable image to use, and retrieve the index= of that image, call:

VkResult vkAcquire=
NextImageKHR(
    VkDevice                                    device,
    VkSwapchainKHR                              swapchain,
    uint64_t                                    timeout,
    VkSemaphore                                 semaphore,
    VkFence                                     fence,
    uint32_t*                                   pImageIndex);
  • device is the device associated with swapchain= .

  • swapchain is the non-retired swapchain from which an image = is being acquired.

  • timeout specifies how long the function waits, in nanosecon= ds, if no image is available.

  • semaphore is VK_NULL_HANDLE or a semaph= ore to signal.

  • fence is VK_NULL_HANDLE or a fence to s= ignal.

  • pImageIndex is a pointer to a uint32_t that is= set to the index of the next image to use (i.e. an index into the array of images returned by vkGetSwapchainImagesKHR).

Valid Usage
  • swapchain must not be in the= retired state

  • If semaphore is not VK_NULL_HANDLE it must be unsignaled

  • If semaphore is not VK_NULL_HANDLE it must not have any uncompleted signal or wait operations pending

  • If fence is not VK_NULL_HANDLE it must be unsignaled and must not be associated with any other que= ue command that has not yet completed execution on that queue

  • semaphore and fence must= not both be equal to VK_NULL_HANDLE

  • If the number of currently acquired images is greater than the difference between the number of images in swapchain and the v= alue of VkSurfaceCapabilitiesKHR::minImageCo= unt as returned by a call to vkGetPhysicalDeviceSurf= aceCapabilities2KHR with the surface used to create swapchain, timeout must not be UINT64_MAX

Valid Usage (Implicit)
  • device<= /code> must be a valid VkDevice handle

  • swap= chain must be a valid VkSwap= chainKHR handle

  • If s= emaphore is not VK_NULL_HANDLE, semaphore<= /code> must be a valid VkSemaphore<= /code> handle

  • If fence= is not VK_NULL_HANDLE, fence must be a valid VkFence handle

  • pI= mageIndex must be a valid pointer = to a uint32_t value

  • If sema= phore is a valid handle, it must h= ave been created, allocated, or retrieved from device

  • If fence is a valid handle, it must have been= created, allocated, or retrieved from device

  • Both of dev= ice, and swapchain that are valid handles must have been created, allocated, or retrieved from t= he same VkInstance

Host Synchronization
  • Host access to swapchain must be externally synchronized

  • Host access to semaphore must be externally synchronized

  • Host access to fence must= be externally synchronized

Return Codes
Success
  • VK_SUCCESS

  • VK_TIMEOUT

  • VK_NOT_READY

  • VK_SUBOPTIMAL_KHR

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_OUT_OF_DATE_KHR

  • VK_ERROR_SURFACE_LOST_KHR

When successful, vkAcquireNextImageKHR acquires a presentab= le image from swapchain that an application ca= n use, and sets pImageIndex to the index of that image within the swapchain. The presentation engine may not have fini= shed reading from the image at the time it is acquired, so the application must use semaphore and/or fence to ensure that the image layout and contents are not mod= ified until the presentation engine reads have completed. The order in which images are acquired is implementation-dependent, and may be different than the order the images were presented.

If timeout is zero, then vkAcquireNextImageKHR= does not wait, and will either successfully acquire an image, or fail and return VK_NOT_READY if no image is available.

If the specified timeout period expires before an image is acquired, vkAcquireNextImageKHR returns VK_TIMEOUT. If timeout is UINT64_MAX, the timeout period is t= reated as infinite, and vkAcquireNextImageKHR will block until an image = is acquired or an error occurs.

An image will eventually be acquired if the number of images that the application has currently acquired (but not yet presented) is less than or equal to the difference between the number of images in swapchain and the value of VkSurfaceCapabilitiesKHR::= minImageCount. If the number of currently acquired images is greater than this, vkAcquireNextImage should no= t be called; if it is, timeout must not be UINT64_MAX.

If an image is acquired successfully, vkAcquireNextImage must either return VK_SUCCESS, or VK_SUBOPTIMAL_KHR if the sw= apchain no longer matches the surface properties exactly, but can still be used for presentation.

Note

This may happen, for example, if the p= latform surface has been resized but the platform is able to scale the presented images to the new size to produce valid surface updates. It is up to the application to decide whether it prefers to continue using the current swapchain in this state, or to re-create the swapchain to bette= r match the platform surface properties.

If the swapchain images no longer match native surface properties, eithe= r VK_SUBOPTIMAL_KHR or VK_ERROR_OUT_OF_DATE_KHR must be returned. If VK_ERROR_OUT_OF_DATE_KHR is returned, no image is acquired = and attempts to present previously acquired images to the swapchain will also fail with VK_ERROR_OUT_OF_DATE_KHR. Applications need to create a new swapchain for the surface to continue presenting if VK_ERROR_OUT_OF_DATE_KHR is returned.

If device loss occurs (see Lost Device) b= efore the timeout has expired, vkAcquireNextImageKHR must return in finite time with either one of the allowed success codes, or VK_ERROR_DEVICE_LOST.

If semaphore is not VK_NULL_HANDLE, the= semaphore must be unsignaled, with no signal or wait operations pending. It will become signaled when the application can use the image.

Note

Use of semaphore allows rendering operations to be recorded= and submitted before the presentation engine has completed its use of the image= .

If fence is not equal to VK_NULL_HANDLE= , the fence must be unsignaled, with no signal operations pending. It will become signaled when the application can use the image.

Note

Applications should not rely on = vkAcquireNextImageKHR blocking in order to meter their rendering speed. The implementation may return from this f= unction immediately regardless of how many presentation requests are queued, and regardless of when queued presentation requests will complete relative to the call. Instead, applications can use fence= to meter their frame generation work to match the presentation rate.

An application must wait until either = the semaphore or fence is signaled before accessing the image=E2=80=99s data.

Note

When the presentable image will be accessed by some stage S, the recommended idiom for ensuring correct synchronization is:

  • The VkSubmitInfo used to submit the image layout trans= ition for execution includes vkAcquireNextImageKHR::semaphore in its pWaitSemaphores member, with the corresponding element of pWaitDstStageMask including S.

  • The synchronization command that performs any necessary image layout transition includes S in b= oth the srcStageMask and dstStageMask.

After a successful return, the image indicated by pImageIndex and its data will be unmodified compared to when it was presented.

Note

Exclusive ownership of presentable images corresponding to a swapchain created with VK_SHARING_MODE_EXCLUSIVE as defined in Resource Sharing is not altered by a call to vkAcquireNextImageKHR. That means upon the first acquisition from such a swapchain presentable images are not owned by any queue family, while at subsequent acquisitions the presentable images remain owned by the queue family the image was previously presented on.

The possible return values for vkAcquireNextImageKHR depend= on the timeout provided:

  • VK_SUCCESS is returned if an image became available.

  • VK_ERROR_SURFACE_LOST_KHR if the surface becomes no longer available.

  • VK_NOT_READY is returned if timeout is zero an= d no image was available.

  • VK_TIMEOUT is returned if timeout is greater t= han zero and less than UINT64_MAX, and no image became available within the= time allowed.

  • VK_SUBOPTIMAL_KHR is returned if an image became available,= and the swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully.

Note

This may happen, for example, if the p= latform surface has been resized but the platform is able to scale the presented images to the new size to produce valid surface updates. It is up to the application to decide whether it prefers to continue using the current swapchain indefinitely or temporarily in this state, or to re-create the swapchain to better match the platform surface properties.

  • VK_ERROR_OUT_OF_DATE_KHR is returned if the surface has cha= nged in such a way that it is no longer compatible with the swapchain, and further presentation requests using the swapchain will fail. Applications must query the new surface p= roperties and recreate their swapchain if they wish to continue presenting to the surface.

If the native surface and presented image sizes no longer match, presentation may fail. If presentation does succeed, parts of the native surface may be undefined, parts of the presented image may have bee= n clipped before presentation, and/or the image may have been scaled (un= iformly or not uniformly) before presentation. It is the application=E2=80=99s responsibility to detect surface size chang= es and react appropriately. If presentation fails because of a mismatch in the surface and presented image sizes, a VK_ERROR_OUT_OF_DATE_KHR error will be returned= .

To acquire an available presentable image to use, and retrieve the index= of that image, call:

VkResult vkAcquire=
NextImage2KHR(
    VkDevice                                    device,
    const VkAcquireNextImageInfoKHR*      =
      pAcquireInfo,
    uint32_t*                                   pImageIndex);
  • device is the device associated with swapchain= .

  • pAcquireInfo is a pointer to a structure of type VkAcquireNextImageInfoKHR containing paramet= ers of the acquire.

  • pImageIndex is a pointer to a uint32_t that is= set to the index of the next image to use.

Valid Usage
  • If the number of currently acquired images is greater than the difference between the number of images in the swapchain membe= r of pAcquireInfo and the value of VkSurfaceCapabilitiesKHR::minImageCount= as returned by a call to vkGetPhysicalDeviceSurf= aceCapabilities2KHR with the surface used to create swapchain, the timeo= ut member of pAcquireInfo must not be = UINT64_MAX

Valid Usage (Implicit)
  • device= must be a valid VkDevice handle

  • = pAcquireInfo must be a valid point= er to a valid VkAcquireNextImageInfoKHR structure

  • p= ImageIndex must be a valid pointer= to a uint32_t value

Return Codes
Success
  • VK_SUCCESS

  • VK_TIMEOUT

  • VK_NOT_READY

  • VK_SUBOPTIMAL_KHR

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_OUT_OF_DATE_KHR

  • VK_ERROR_SURFACE_LOST_KHR

The VkAcquireNextImageInfoKHR structure is defined as:

typedef struct VkAcquireNextIma=
geInfoKHR {
    VkStructureType    sType;
    const void*        pNext;
    VkSwapchainKHR     swapchain;
    uint64_t           timeout;
    VkSemaphore        semaphore;
    VkFence            fence;
    uint32_t           deviceMask;
} VkAcquireNextImageInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • swapchain is a non-retired swapchain from which an image is acquired.

  • timeout specifies how long the function waits, in nanosecon= ds, if no image is available.

  • semaphore is VK_NULL_HANDLE or a semaphore to = signal.

  • fence is VK_NULL_HANDLE or a fence to signal.<= /p>

  • deviceMask is a mask of physical devices for which the swap= chain image will be ready to use when the semaphore or fence is signaled.

If vkAcquireNextImageKHR is used, the device = mask is considered to include all physical devices in the logical device.

Note

vkAcquireNextImage2KHR signals at most one s= emaphore, even if the application requests waiting for multiple physical devices to be ready via the deviceMask. However, only a single physical device can wait on that semaphore, since the semaphore becomes unsignaled when the wait succeeds. For other physical devices to wait for the image to be ready, it is necessary for the application to submit semaphore signal operation(s) to that first physical device to signal additional semaphore(s) after the wait succeeds, which the other physical device(s) can wait upon.

Valid Usage
  • swapchain must not be in the= retired state

  • If semaphore is not VK_NULL_HANDLE it must be unsignaled

  • If semaphore is not VK_NULL_HANDLE it must not have any uncompleted signal or wait operations pending

  • If fence is not VK_NULL_HANDLE it must be unsignaled and must not be associated with any other que= ue command that has not yet completed execution on that queue

  • semaphore and fence must= not both be equal to VK_NULL_HANDLE

  • deviceMask must be a valid d= evice mask

  • deviceMask must not be zero<= /p>

  • semaphore and fence must= not both be equal to VK_NULL_HANDLE.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_ACQU= IRE_NEXT_IMAGE_INFO_KHR

  • pNext must be NULL

  • = swapchain must be a valid Vk= SwapchainKHR handle

  • If semaphore is not VK_NULL_HANDLE, semaph= ore must be a valid VkSemaph= ore handle

  • If f= ence is not VK_NULL_HANDLE, fence <= strong class=3D"purple">must be a valid VkFence handl= e

  • Each of fence, semaphore, and swapchain that are = valid handles must have been created, all= ocated, or retrieved from the same VkInstance

Host Synchronization
  • Host access to swapchain must be externally synchronized

  • Host access to semaphore must be externally synchronized

  • Host access to fence must= be externally synchronized

After queueing all rendering commands and transitioning the image to the correct layout, to queue an image for presentation, call:

VkResult vkQueuePr=
esentKHR(
    VkQueue                                     queue,
    const VkPresentInfoKHR*               =
      pPresentInfo);
  • queue is a queue that is capable of presentation to the tar= get surface=E2=80=99s platform on the same device as the image=E2=80=99s swapch= ain.

  • pPresentInfo is a pointer to an instance of the VkPresentInfoKHR structure specifying the parameters = of the presentation.

Note

There is no requirement for an application to present images in the same order that they were acquired - applications can arbitrarily present any image that is currently acquired.

Valid Usage
  • Each element of pSwapchains member of pPresentInfo must be a swapchain that is created for a surface for which presentation is supported from queue as determined using a call to vkGetPhysicalDeviceSurfaceSupportKHR

  • If more than one member of pSwapchains was created from a disp= lay surface, all display surfaces referenced that refer to the same display must use the same display mode

  • When a semaphore unsignal operation defined by the elements of the pWaitSemaphores member of pPresentInfo executes o= n queue, no other queue must b= e waiting on the same semaphore.

  • All elements of the pWaitSemaphores member of pPresentIn= fo must be semaphores that are signaled, or = have semaphore signal operations previously submitted for execution.

Any writes to memory backing the images referenced by the pImageIndices and pSwapchains members of pP= resentInfo, that are available before vkQueuePresentKHR is execu= ted, are automatically made visible to the read access performed by the presentation engine. This automatic visibility operation for an image happens-after the semaphor= e signal operation, and happens-before the presentation engine accesses the image.

Queueing an image for presentation defines a set of queue operations= , including waiting on the semaphores and submitting a presentation request t= o the presentation engine. However, the scope of this set of queue operations does not include the actual processing of the image by the presentation engine.

If vkQueuePresentKHR fails to enqueue the corresponding set= of queue operations, it may return VK_ERROR_= OUT_OF_HOST_MEMORY or VK_ERROR_OUT_OF_DEVICE_MEMORY. If it does, the implementation must ensur= e that the state and contents of any resources or synchronization primitives referenced is unaffected by the call or its failure.

If vkQueuePresentKHR fails in such a way that the implement= ation is unable to make that guarantee, the implementation = must return VK_ERROR_DEVICE_LOST.

However, if the presentation request is rejected by the presentation eng= ine with an error VK_ERROR_OUT_OF_DATE_KHR or VK_ERROR_SURFACE_LOST_KHR, the set of queue operations are sti= ll considered to be enqueued and thus any semaphore to be waited on gets unsignaled when the corresponding queue operation is complete.

Valid Usage (Implicit)
  • queue= must be a valid VkQueue han= dle

  • pPres= entInfo must be a valid pointer to= a valid VkPresentInfoKHR structure

Host Synchronization
  • Host access to queue must= be externally synchronized

  • Host access to pPresentInfo.pWaitSemaphores[] must be externally synchronized

  • Host access to pPresentInfo.pSwapchains[] must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

  • VK_SUBOPTIMAL_KHR

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

  • VK_ERROR_OUT_OF_DATE_KHR

  • VK_ERROR_SURFACE_LOST_KHR

The VkPresentInfoKHR structure is defined as:

typedef struct VkPresentInfoKHR=
 {
    VkStructureType          sType;
    const void*              pNext;
    uint32_t                 waitSemaphoreCount;
    const VkSemaphore*       pWaitSemaphor=
es;
    uint32_t                 swapchainCount;
    const VkSwapchainKHR*    pSwapchains;
    const uint32_t*          pImageIndices=
;
    VkResult*                pResults;
} VkPresentInfoKHR;

Before an application can present an i= mage, the image=E2=80=99s layout must be transitioned to the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout, or for a shared presentable image the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR layout.

Note

When transitioning the image to VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, there is no need to delay sub= sequent processing, or perform any visibility operations (as vkQ= ueuePresentKHR performs automatic visibility operations). To achieve this, the dstAccessMask member of the VkImageMemoryBarrier sho= uld be set to 0, and the dstStageMask parameter should be set to VK_PIPEL= INE_STAGE_BOTTOM_OF_PIPE_BIT.

Valid Usage
  • Each element of pImageIndices must be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pSwapchains array, and the presented image subresource must be in the VK_IMAGE_LAYOUT_PRES= ENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR layout at the time the operation is executed on a VkDevice

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PRESENT_INFO_= KHR

  • Each pNext= member of any structure (including this one) in the pNext cha= in must be either NULL or a = pointer to a valid instance of VkDeviceGroupPr= esentInfoKHR, VkDisplayPresentInfoKHR, VkPresentRegionsKHR, or VkP= resentTimesInfoGOOGLE

  • Each sType member in the pNext chain must be unique

  • If = waitSemaphoreCount is not 0, pWaitSemaphores must be a valid pointer to an array of= waitSemaphoreCount valid VkSemaphore handles

  • pSwapch= ains must be a valid pointer to an= array of swapchainCount valid VkSwapchainKHR han= dles

  • pImag= eIndices must be a valid pointer t= o an array of swapchainCount uint32_t values

  • If pResult= s is not NULL, pResults must be a valid pointer to an array of swapchainCount= VkResult values

  • sw= apchainCount must be greater than = 0

  • Both of the elements o= f pSwapchains, and the elements of pWaitSemaphores that are valid handles must have been c= reated, allocated, or retrieved from the same VkInstance

When the VK_KHR_incremental_present extension is enabled, a= dditional fields can be specified that allow an app= lication to specify that only certain rectangular regions of the presentable images of a swapchain are changed. This is an optimization hint that a presentation engine may use to only update the region of a surface that is actually changing. The application still must ensure that al= l pixels of a presented image contain the desired values, in case the presentation engine ignores this hint. An application can provide this hint by i= ncluding the VkPresentRegionsKHR structure in the pNext chain = of the VkPresentInfoKHR structure.

The VkPresentRegionsKHR structure is defined as:

typedef struct VkPresentRegions=
KHR {
    VkStructureType              sType;
    const void*                  pNext;
    uint32_t                     swapchainCount;
    const VkPresentRegionKHR*    pRegions;
} VkPresentRegionsKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • swapchainCount is the number of swapchains being presented = to by this command.

  • pRegions is NULL or a pointer to an array of VkPresentRegionKHR elements with swapchainCount e= ntries. If not NULL, each element of pRegions contains th= e region that has changed since the last present to the swapchain in the corresponding entry in the VkPresentInfoKHR::pSwapchains array.=

Valid Usage
  • swapchainCount must be the s= ame value as VkPresentInfoKHR::swapchainCount, where VkPresentInfoKHR is in the pNext-chain of this VkPresentRegionsKHR structure.

Valid Usage (Implicit)
  • sType <= strong class=3D"purple">must be VK_STRUCTURE_TYPE_PRESENT_RE= GIONS_KHR

  • If pReg= ions is not NULL, pRegions must be a valid pointer to an array of swapchain= Count valid VkPresentRegionKHR structures

  • swapchainCount must be greater th= an 0

For a given image and swapchain, the region to present is specified by t= he VkPresentRegionKHR structure, which is defined as:

typedef struct VkPresentRegionK=
HR {
    uint32_t                 rectangleCount;
    const VkRectLayerKHR*    pRectangles;
} VkPresentRegionKHR;
  • rectangleCount is the number of rectangles in pRectan= gles, or zero if the entire image has changed and should be presented.

  • pRectangles is either NULL or a pointer to an = array of VkRectLayerKHR structures. The VkRectLayerKHR structure is the framebuffer coordinates, p= lus layer, of a portion of a presentable image that has changed and must be presented. If non-NULL, each entry in pRectangles is a recta= ngle of the given image that has changed since the last image was presented to the given swapchain.

Valid Usage (Implicit)
  • If re= ctangleCount is not 0, and pRectangles is = not NULL, pRectangles mu= st be a valid pointer to an array of rectangleCount v= alid VkRectLayerKHR structures

The VkRectLayerKHR structure is defined as:

typedef struct VkRectLayerKHR {
    VkOffset2D    offset;
    VkExtent2D    extent;
    uint32_t      layer;
} VkRectLayerKHR;
  • offset is the origin of the rectangle, in pixels.

  • extent is the size of the rectangle, in pixels.

  • layer is the layer of the image. For images with only one layer, the value of layer must be 0.

Valid Usage
  • The sum of offset and extent must be no greater than the imageExtent member of the VkSwapchainCreateInfoKHR structure given to vkCreateSwapchainKHR.

  • layer must be less than imageArrayLayers member of the VkSwapchainCreateInfoKHR structure given to vkCreateSwapchainKHR.

Some platforms allow the size of a surface to change, and then scale the pixels of the image to fit the surface. VkRectLayerKHR specifies pixels of the swapchain=E2=80=99s ima= ge(s), which will be constant for the life of the swapchain.

When the VK_KHR_display_swapchain extension is enabled addi= tional fields can be specified when presenting an image= to a swapchain by setting VkPresentInfoKHR::pNext to point to an i= nstance of the VkDisplayPresentInfoKHR structure.

The VkDisplayPresentInfoKHR structure is defined as:

typedef struct VkDisplayPresent=
InfoKHR {
    VkStructureType    sType;
    const void*        pNext;
    VkRect2D           srcRect;
    VkRect2D           dstRect;
    VkBool32           persistent;
} VkDisplayPresentInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • srcRect is a rectangular region of pixels to present. It must be a subset of the image being pr= esented. If VkDisplayPresentInfoKHR is not specified, this region will = be assumed to be the entire presentable image.

  • dstRect is a rectangular region within the visible region o= f the swapchain=E2=80=99s display mode. If VkDisplayPresentInfoKHR is not specified, this region will = be assumed to be the entire visible region of the visible region of the swapchain=E2=80=99s mode. If the specified rectangle is a subset of the display mode=E2=80=99s visibl= e region, content from display planes below the swapchain=E2=80=99s plane wil= l be visible outside the rectangle. If there are no planes below the swapchain=E2=80=99s, the area outside the specified rectangle will be black. If portions of the specified rectangle are outside of the display=E2=80=99s visible region, pixels mapping only to those portions of the rectangle will be discarded.

  • persistent: If this is VK_TRUE, the display en= gine will enable buffered mode on displays that support it. This allows the display engine to stop sending content to the display until a new image is presented. The display will instead maintain a copy of the last presented image. This allows less power to be used, but may increase presentation latency. If VkDisplayPresentInfoKHR is not specified, persistent mode w= ill not be used.

If the extent of the srcRect and dstRect are n= ot equal, the presented pixels will be scaled accordingly.

Valid Usage
  • srcRect must specify a recta= ngular region that is a subset of the image being presented

  • dstRect must specify a recta= ngular region that is a subset of the visibleRegion parameter of the display mode the swapchain bein= g presented uses

  • If the persistentContent member of the VkDisplayPropertiesKHR structure returned by vkGetPhysicalDeviceDisplayPropertiesKHR for the display the present operation targets then persistent must be VK_FALSE

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DISPLA= Y_PRESENT_INFO_KHR

The VkDeviceGroupPresentInfoKHR structure is defined as:

typedef struct VkDeviceGroupPre=
sentInfoKHR {
    VkStructureType                        sType;
    const void*                            pNext;
    uint32_t                               swapchainCount;
    const uint32_t*                       =
 pDeviceMasks;
    VkDeviceGroupPresentModeFlagBitsKHR    mode;
} VkDeviceGroupPresentInfoKHR;

If mode is VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR= , then each element of pDeviceMasks selects which instance of the swapchai= n image is presented. Each element of pDeviceMasks must have exactly one bit set, and the corresponding physical device must have a= presentation engine as reported by VkDeviceGroupPresentCapabilitiesKHR= .

If mode is VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KH= R, then each element of pDeviceMasks selects which instance of the swa= pchain image is presented. Each element of pDeviceMasks must have exactly one bit set, and some physical device in the logical device must include that bit in its VkDeviceGroupPresentCapabilitiesKHR::presentMask.

If VkDeviceGroupPresentInfoKHR is not provided or swa= pchainCount is zero then the masks are considered to be 1. If VkDeviceGroupPresentInfoKHR is not provided, mode is considered to be VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR.

Valid Usage
Valid Usage (Implicit)
  • sType<= /code> must be VK_STRUCTURE_TYPE_DE= VICE_GROUP_PRESENT_INFO_KHR

  • I= f swapchainCount is not 0, pDeviceMasks must be a valid pointer to an array o= f swapchainCount uint32_t values

  • mod= e must be a valid VkDeviceGroupPresentModeFlagBitsKHR value

When the VK_GOOGLE_display_timing extension is enabled, additional fields can be specified that allow an app= lication to specify the earliest time that an image should be displayed. This allows an application to avoid stutter that is caused by an image bein= g displayed earlier than planned. Such stuttering can occur with both fixed and variable-refresh-rate displays, because stuttering occurs when the geometry is not correctly positioned for when the image is displayed. An application can instruct the presentat= ion engine that an image should not be displayed earlier than a specified time by including the VkPresentTimesInfoGOOGLE structure in the pNext c= hain of the VkPresentInfoKHR structure.

The VkPresentTimesInfoGOOGLE structure is defined as:

typedef struct VkPresentTimesIn=
foGOOGLE {
    VkStructureType               sType;
    const void*                   pNext;
    uint32_t                      swapchainCount;
    const VkPresentTimeGOOGLE*    pTimes;
} VkPresentTimesInfoGOOGLE;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • swapchainCount is the number of swapchains being presented = to by this command.

  • pTimes is NULL or a pointer to an array of VkPresentTimeGOOGLE elements with swapchainCount = entries. If not NULL, each element of pTimes contains the = earliest time to present the image corresponding to the entry in the VkPresentInfoKHR::pImageIndices array.

Valid Usage
  • swapchainCount must be the s= ame value as VkPresentInfoKHR::swapchainCount, where VkPresentInfoKHR is in the pNext chain of this VkPresentTimesInfoGOOGLE structure.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PRESE= NT_TIMES_INFO_GOOGLE

  • If p= Times is not NULL, pTimes must be a valid pointer to an array of swapchainCou= nt VkPresentTimeGOOGLE structures

  • = swapchainCount must be great= er than 0

The VkPresentTimeGOOGLE structure is defined as:

typedef struct VkPresentTimeGOO=
GLE {
    uint32_t    presentID;
    uint64_t    desiredPresentTime;
} VkPresentTimeGOOGLE;
  • presentID is an application-provided identification value, = that can be used with the results of vkGetPastPresentationTimingGOOGLE, i= n order to uniquely identify this present. In order to be useful to the application, it shoul= d be unique within some period of time that is meaningful to the application.

  • desiredPresentTime specifies that the image given should not be displayed to the user any earlier than this time. desiredPresentTime is a time in nanoseconds, relative to a monotonically-increasing clock (e.g. CLOCK_MONOTONIC (see clock_gettime(2)) on Android and Linux). A value of zero specifies that the presentation engine may display the image at any time. This is useful when the application desires to provide presentID, but doesn=E2=80=99t need a specific desiredPresentTime.

vkQueuePresentKHR, releases the acquisition of the images r= eferenced by imageIndices. The queue family corresponding to the queue vkQueuePresentKHR = is executed on must have ownership of the pr= esented images as defined in Resource Sharing. vkQueuePresentKHR does not alter the queue family ownership, b= ut the presented images must not be used again b= efore they have been reacquired using vkAcquireNextImageKHR.

The processing of the presentation happens in issue order with other que= ue operations, but semaphores have to be used to ensure that prior rendering and other commands in the specified queue complete before the presentation begins. The presentation command itself does not delay processing of subsequent commands on the queue, however, presentation requests sent to a particular queue are always performed in order. Exact presentation timing is controlled by the semantics of the presentatio= n engine and native platform in use.

If an image is presented to a swapchain created from a display surface, = the mode of the associated display will be updated, if necessary, to match the mode specified when creating the display surface. The mode switch and presentation of the specified image will be performed a= s one atomic operation.

The result codes VK_ERROR_OUT_OF_DATE_KHR and VK_SUBO= PTIMAL_KHR have the same meaning when returned by vkQueuePresentKHR as th= ey do when returned by vkAcquireNextImageKHR. If multiple swapchains are presented, the result code is determined applyin= g the following rules in order:

  • If the device is lost, VK_ERROR_DEVICE_LOST is returned.

  • If any of the target surfaces are no longer available the error VK_ERROR_SURFACE_LOST_KHR is returned.

  • If any of the presents would have a result of VK_ERROR_OUT_OF_DATE_KHR if issued separately then VK_ERROR_OUT_OF_DATE_KHR is returned.

  • If any of the presents would have a result of VK_SUBOPTIMAL_KHR if issued separately then VK_SUBOPTIMAL_KHR is returned.

  • Otherwise VK_SUCCESS is returned.

Presentation is a read-only operation that will not affect the content o= f the presentable images. Upon reacquiring the image and transitioning it away from the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout, the contents will be t= he same as they were prior to transitioning the image to the present source layout and presenting it. However, if a mechanism other than Vulkan is used to modify the platform window associated with the swapchain, the content of all presentable images in the swapchain becomes undefined.

Note

The application can continue to presen= t any acquired images from a retired swapchain as long as the swapchain has not entered a state that causes vkQueuePresentKHR to return VK_ERROR_OUT_OF_DA= TE_KHR.

30.9. Hdr Metadata

To improve color reproduction of content it is useful to have informatio= n that can be used to better reproduce the colors as seen on the mastering display. That information can be provided to an implementation by calling vkSetHdrMetadataEXT. The metadata will be applied to the specified VkSwapchainKHR o= bjects at the next vkQueuePresentKHR call using that VkSwapchai= nKHR object. The metadata will persist until a subsequent vkSetHdrMetadataEXT changes it. The definitions below are from the associated SMPTE 2086, CTA 861.3 and CIE 15:2004 specifications.

The definition of vkSetHdrMetadataEXT is:

void vkSetHdrMetadataEXT(
    VkDevice                                    device,
    uint32_t                                    swapchainCount,
    const VkSwapchainKHR*                 =
      pSwapchains,
    const VkHdrMetadataEXT*               =
      pMetadata);
  • device is the logical device where the swapchain(s) were cr= eated.

  • swapchainCount is the number of swapchains included in pSwapchains.

  • pSwapchains is a pointer to the array of swapchainCou= nt VkSwapchainKHR handles.

  • pMetadata is a pointer to the array of swapchainCount= VkHdrMetadataEXT structures.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pSwa= pchains must be a valid pointer to= an array of swapchainCount valid VkSwapchainKHR = handles

  • pMetad= ata must be a valid pointer to an = array of swapchainCount valid VkHdrMetadataEXT st= ructures

  • swapchainCount must be greater th= an 0

  • Both of devic= e, and the elements of pSwapchains must have been created, allocated, or retrieved from the same= VkInstance

typedef struct VkXYColorEXT {
    float    x;
    float    y;
} VkXYColorEXT;

Chromaticity coordinates x and y are as specified in CIE 15:2004 =E2=80=9CCalculation of chromaticity coordinates=E2=80=9D (Section 7.3) and= are limited to between 0 and 1 for real colors for the mastering display.

typedef struct VkHdrMetadataEXT=
 {
    VkStructureType    sType;
    const void*        pNext;
    VkXYColorEXT       displayPrimaryRed;
    VkXYColorEXT       displayPrimaryGreen;
    VkXYColorEXT       displayPrimaryBlue;
    VkXYColorEXT       whitePoint;
    float              maxLuminance;
    float              minLuminance;
    float              maxContentLig=
htLevel;
    float              maxFrameAvera=
geLightLevel;
} VkHdrMetadataEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • displayPrimaryRed is the mastering display=E2=80=99s red pr= imary in chromaticity coordinates

  • displayPrimaryGreen is the mastering display=E2=80=99s gree= n primary in chromaticity coordinates

  • displayPrimaryBlue is the mastering display=E2=80=99s blue = primary in chromaticity coordinates

  • whitePoint is the mastering display=E2=80=99s white-point i= n chromaticity coordinates

  • maxLuminance is the maximum luminance of the mastering disp= lay in nits

  • minLuminance is the minimum luminance of the mastering disp= lay in nits

  • maxContentLightLevel is content=E2=80=99s maximum luminance= in nits

  • maxFrameAverageLightLevel is the maximum frame average ligh= t level in nits

Note

The validity and use of this data is outside the scope of Vulkan and thu= s no Valid Usage is given.

31. Extended Functionality

Additional functionality may be provid= ed by layers or extensions. A layer cannot add or modify Vulkan comma= nds, while an extension may do so.

The set of layers to enable is specified when creating an instance, and those layers are able to intercept any Vulkan command dispatched to that instance or any of its child objects.

Extensions can operate at either the instance or device extension sc= ope. Enabled instance extensions are able to affect the operation of the instanc= e and any of its child objects, while device extensions may only be available on a subset of physical devices, must be = individually enabled per-device, and only affect the operation of the devices where they are enabled.

Note

Examples of these might be:

  • Whole API validation is an example of a layer.

  • Debug capabilities might make a good instance extension.

  • A layer that provides implementation-specific performance telemetry and analysis could be a layer that is only active for devices created from compatible physical devices.

  • Functions to allow an application to use additional implementation features beyond the core would be a good candidate for a device extension.

31.1. Layers

When a layer is enabled, it inserts itself into the call chain for Vulka= n commands the layer is interested in. A common use of layers is to validate application behavior during development. For example, the implementation will not check that Vulkan enums used by th= e application fall within allowed ranges. Instead, a validation layer would do those checks and flag issues. This avoids a performance penalty during production use of the application because those layers would not be enabled in production.

Vulkan layers may wrap object handles = (i.e. return a different handle value to the application than that generated by the implementation). This is generally discouraged, as it increases the probability of incompatibilities with new extensions. The validation layers wrap handles in order to track the proper use and destruction of each object. See the =E2=80=9CVulkan Loader Specification and Architecture Overview=E2=80=9D document for additional information.

To query the available layers, call:

VkResult vkEnumera=
teInstanceLayerProperties(
    uint32_t*                                   pPropertyCount,
    VkLayerProperties*                          pProperties);
  • pPropertyCount is a pointer to an integer related to the nu= mber of layer properties available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkLayerProperties structures.

If pProperties is NULL, then the number of lay= er properties available is returned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return= the variable is overwritten with the number of structures actually written to pProperties. If pPropertyCount is less than the number of layer properties available, at most pPropertyCount structures will be written. If pPropertyCount is smaller than the number of layers availab= le, VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate that not all the available layer properties were returned.

The list of available layers may change at any time due to actions outsi= de of the Vulkan implementation, so two calls to vkEnumerateInstanceLayerProperties with the same parameters may return different results, or retrieve different pPropertyCount= values or pProperties contents. Once an instance has been created, the layers enabled for that instance wil= l continue to be enabled and valid for the lifetime of that instance, even if some of them become unavailable for future instances.

Valid Usage (Implicit)
  • pPropertyCount must = be a valid pointer to a uint32_t value

  • = If the value referenced by pPropertyCount is not 0<= /code>, and pProperties is not NULL, pPrope= rties must be a valid pointer to a= n array of pPropertyCount VkLayerProperties struc= tures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkLayerProperties structure is defined as:

typedef struct VkLayerPropertie=
s {
    char        layerName[VK_MAX_EXT=
ENSION_NAME_SIZE];
    uint32_t    specVersion;
    uint32_t    implementationVersion;
    char        description[VK_MAX_D=
ESCRIPTION_SIZE];
} VkLayerProperties;
  • layerName is a null-terminated UTF-8 string specifying the = name of the layer. Use this name in the ppEnabledLayerNames array passed in the VkInstanceCreateInfo structure to enable this lay= er for an instance.

  • specVersion is the Vulkan version the layer was written to, encoded as described in the API Version Numbers and Semantics section.

  • implementationVersion is the version of this layer. It is an integer, increasing with backward compatible changes.

  • description is a null-terminated UTF-8 string providing add= itional details that can be used by the applicati= on to identify the layer.

To enable a layer, the name of the layer should= be added to the ppEnabledLayerNames member of VkInstance= CreateInfo when creating a VkInstance.

Loader implementations may provide mec= hanisms outside the Vulkan API for enabling specific layers. Layers enabled through such a mechanism are implicitly enabled, wh= ile layers enabled by including the layer name in the ppEnabledLayerNames= member of VkInstanceCreateInfo are explicitly= enabled. Except where otherwise specified, implicitly enabled and explicitly enabled layers differ only in the way they are enabled. Explicitly enabling a layer that is implicitly enabled has no additional effect.

31.1.1. Device L= ayer Deprecation

Previous versions of this specification distinguished between instance a= nd device layers. Instance layers were only able to intercept commands that operate on VkInstance and VkPhysicalDevice, except they were= not able to intercept vkCreateDevice. Device layers were enabled for individual devices when they were created, and could only intercept commands operating on that device or its child objects.

Device-only layers are now deprecated, and this specification no longer distinguishes between instance and device layers. Layers are enabled during instance creation, and are able to intercept all commands operating on that instance or any of its child objects. At the time of deprecation there were no known device-only layers and no compelling reason to create one.

In order to maintain compatibility with implementations released prior t= o device-layer deprecation, applications should still enumerate and enable device layers. The behavior of vkEnumerateDeviceLayerProperties and valid usa= ge of the ppEnabledLayerNames member of VkDeviceCreateInfo maximizes compatibility with applications written to work with the previous requirements.

To enumerate device layers, call:

VkResult vkEnumera=
teDeviceLayerProperties(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pPropertyCount,
    VkLayerProperties*                          pProperties);
  • pPropertyCount is a pointer to an integer related to the nu= mber of layer properties available or queried.

  • pProperties is either NULL or a pointer to an = array of VkLayerProperties structures.

If pProperties is NULL, then the number of lay= er properties available is returned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return= the variable is overwritten with the number of structures actually written to pProperties. If pPropertyCount is less than the number of layer properties available, at most pPropertyCount structures will be written. If pPropertyCount is smaller than the number of layers availab= le, VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate that not all the available layer properties were returned.

The list of layers enumerated by vkEnumerateDeviceLayerProperties<= /code> must be exactly the sequence of layers en= abled for the instance. The members of VkLayerProperties for each enumerated layer must be the same as the properties when the layer was enumerated by vkEnumerateInstanceLayerProperties.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The ppEnabledLayerNames and enabledLayerCount = members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations. However, for compatibility, only an empty list of layers or a list that exactly matches the sequence enabled at instance creation time are valid, and validation layers should issue diagno= stics for other cases.

Regardless of the enabled layer list provided in VkDeviceCreateInf= o, the sequence of layers active for a device will be exactly the sequence of layers enabled when the parent instance was created.

31.2. Extensions

Extensions may define new Vulkan comma= nds, structures, and enumerants. For compilation purposes, the interfaces defined by registered extensions, including new structures and enumerants as well as function pointer types for new commands, are defined in the Khronos-supplied vulkan_core.h together with the core API. However, commands defined by extensions may not be available for static linking - in which case function pointers to these commands should be queried at runtime as described in Command= Function Pointers. Extensions may be provided by layers as w= ell as by a Vulkan implementation.

Because extensions may extend or chang= e the behavior of the Vulkan API, extension authors should add support for = their extensions to the Khronos validation layers. This is especially important for new commands whose parameters have been wrapped by the validation layers. See the =E2=80=9CVulkan Loader Specification and Architecture Overview=E2=80=9D document for additional information.

Note

Valid Usage sections for individual commands and structures do not curre= ntly contain which extensions have to be enabled in order to make their use valid, although it might do so in the future. It is defined only in the Valid Usage f= or Extensions section.

To query the available instance extensions, call:

VkResult vkEnumera=
teInstanceExtensionProperties(
    const =
char*                                 pLayerName,
    uint32_t*                                   pPropertyCount,
    VkExtensionProperties*                      pProperties);
  • pLayerName is either NULL or a pointer to a nu= ll-terminated UTF-8 string naming the layer to retrieve extensions from.

  • pPropertyCount is a pointer to an integer related to the nu= mber of extension properties available or queried, as described below.

  • pProperties is either NULL or a pointer to an = array of VkExtensionProperties structures.

When pLayerName parameter is NULL, only extens= ions provided by the Vulkan implementation or by implicitly enabled layers are returned. When pLayerName is the name of a layer, the instance extension= s provided by that layer are returned.

If pProperties is NULL, then the number of ext= ensions properties available is returned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return= the variable is overwritten with the number of structures actually written to pProperties. If pPropertyCount is less than the number of extension propert= ies available, at most pPropertyCount structures will be written. If pPropertyCount is smaller than the number of extensions ava= ilable, VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate that not all the available properties were returned.

Because the list of available layers may change externally between calls= to vkEnumerateInstanceExtensionProperties, two calls may retrieve different results if a pLayerName is available in one call but= not in another. The extensions supported by a layer may also change between two calls, e.g. if the layer implementation is replaced by a different version between thos= e calls.

Valid Usage (Implicit)
  • If pLayerName is not NULL, pLayerNa= me must be a null-terminated UTF-8= string

  • pPropertyCount must be a valid pointer to a uint32_t value

  • If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pP= roperties must be a valid pointer = to an array of pPropertyCount VkExtensionProperties structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_LAYER_NOT_PRESENT

To enable an instance extension, the name of the extension should be added to the ppEnabledExtensionNames member of VkInstanceCreateInfo when creating a VkInstance.

Enabling an extension does not change behavior of functionality exposed = by the core Vulkan API or any other extension, other than making valid the use of the commands, enums and structures defined by that extension.

To query the extensions available to a given physical device, call:

VkResult vkEnumera=
teDeviceExtensionProperties(
    VkPhysicalDevice                            physicalDevice,
    const =
char*                                 pLayerName,
    uint32_t*                                   pPropertyCount,
    VkExtensionProperties*                      pProperties);
  • physicalDevice is the physical device that will be queried.=

  • pLayerName is either NULL or a pointer to a nu= ll-terminated UTF-8 string naming the layer to retrieve extensions from.

  • pPropertyCount is a pointer to an integer related to the nu= mber of extension properties available or queried, and is treated in the same fashion as the vkEnumerateInstanceExtensionPropert= ies::pPropertyCount parameter.

  • pProperties is either NULL or a pointer to an = array of VkExtensionProperties structures.

When pLayerName parameter is NULL, only extens= ions provided by the Vulkan implementation or by implicitly enabled layers are returned. When pLayerName is the name of a layer, the device extensions = provided by that layer are returned.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • If pLayerName is not NULL, pLayerName= must be a null-terminated UTF-8 s= tring

  • pPropertyCount must be a valid pointer to a uint32_t value

  • If the value referenced by pPropertyCount is not = 0, and pProperties is not NULL, pPro= perties must be a valid pointer to= an array of pPropertyCount VkExtensionProperties= structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_LAYER_NOT_PRESENT

The VkExtensionProperties structure is defined as:

typedef struct VkExtensionPrope=
rties {
    char        extensionName[VK_MAX=
_EXTENSION_NAME_SIZE];
    uint32_t    specVersion;
} VkExtensionProperties;
  • extensionName is a null-terminated string specifying the na= me of the extension.

  • specVersion is the version of this extension. It is an integer, incremented with backward compatible changes.

31.2.1. I= nstance Extensions and Device Extensions

This section provides some guidelines and rules for when to expose new functionality as an instance extension, as a device extension, or as both. The decision depends on the scope of the new functionality; such as whether it extends instance-level or device-level functionality. All Vulkan commands, structures, and enumerants are considered either instance-level, physical-device-level, or device-level.

New instance-level extension functionality must= be structured within an instance extension. New device-level extension functionality may be structured within a device extension. Vulkan 1.0 initially required all new physical-device-level extension functionality to be structured within an instance extension. In order to avoid using an instance extension, which often requires loader support, physical-device-level extension functionality may be implemented within device extensions (which must depe= nd on the VK_KHR_get_physical_device_pr= operties2 extension, or on Vulkan 1.1 or later).

31.3. Extension D= ependencies

Some extensions are dependent on other extensions to function. To enable extensions with dependencies, such required extensions <= strong class=3D"purple">must also be enabled through the same API mechanisms when creating an instance with vkCreateInstance or a device with appendix summarizing that extension.

31.4. Extension = Compatibility

By default, all extensions are considered compatible with each other and= any core API version, unless otherwise stated. Thus enabling such extensions does not otherwise alter the behavior of the application.

Each extension that is mutually exclusive or otherwise incompatible with another extension or set of extensions documents them in the ap= pendix summarizing that extension and has a corresponding Valid Usage statement disallowing enabling such an incompatible combination of extensions at VkInstance creation time or VkDevice creation time, depending on the type of extensions participating in the interaction.=

32. Features, Limits, and Formats

Vulkan is designed to support a wide variety of implementations, and as = such there are a number of features, limits, and formats which are not supported on all implementations. Features describe functionality which is optional<= /strong> and which must be explicitly enabled before use. Limits describe implementation-dependent minimums, maximums, and other device characteristics that an application may need to be aware of. Supported buffer and image formats may va= ry across implementations. A minimum set of format features are guaranteed, but others must be explicitly queried before use to ensure they are supported by the implementation.

Note

The features and limits are reported via basic structures (that is VkPhysicalDeviceFeatures and VkPhysicalDeviceLimits), as well as extensible structures (VkPhysicalDeviceFeatures2 and VkPhysicalDeviceProperties2) which were added in VK_KHR_get_physical_device_pr= operties2 and included in Vulkan 1.1. When new features or limits are added in future Vulkan version or extensions, each extension should introdu= ce one new feature structure and/or limit structure (as needed). These structures can be added to the pNext chain of the VkPhysicalDeviceFeatures2 and VkPhysicalDeviceProperties= 2 structures, respectively.

32.1. Features

The Specification defines a set of optional features that may be supported by a Vulkan implementation. Support for features is reported and enabled on a per-feature basis. Features are properties of the physical device.

To query supported features, call:

void vkGetPhysicalDeviceFeatures(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceFeatures*                   pFeatures);
  • physicalDevice is the physical device from which to query t= he supported features.

  • pFeatures is a pointer to a VkPhy= sicalDeviceFeatures structure in which the physical device features are returned. For each feature, a value of VK_TRUE specifies that the featur= e is supported on this physical device, and VK_FALSE specifies that= the feature is not supported.

Valid Usage (Implicit)
  • = physicalDevice must be a va= lid VkPhysicalDevice handle

  • pFeatures must be a valid pointe= r to a VkPhysicalDeviceFeatures structure

Fine-grained features used by a logical device = must be enabled at VkDevice creation time. If a feature is enabled that the physical device does not support, VkDevice creation will fail. If an application uses a feature without enabling it at VkDevice creation time, the device behavior is undefined. The validation layer will warn if features are used without being enabled.<= /p>

The fine-grained features are enabled by passing a pointer to the VkPhysicalDeviceFeatures structure via the pEnabledFeatu= res member of the VkDeviceCreateInfo structure that is passed into= the vkCreateDevice call. If a member of pEnabledFeatures is set to VK_TRUE= or VK_FALSE, then the device will be created with the indicated f= eature enabled or disabled, respectively. Features can also be enabled by using the= VkPhysicalDeviceFeatures2 structure.

If an application wishes to enable all features supported by a device, i= t can simply pass in the VkPhysicalDe= viceFeatures structure that was previously returned by vkGetPhysicalDeviceFeatures. To disable an individual feature, the application = can set the desired member to VK_FALSE in the same structure. Setting pEnabledFeatures to NULL and not including a VkPhysicalDeviceFeatures2 in the pNext member of VkDeviceCreateInfo is equivalent to setting all members of the structure to VK_FALSE.

Note

Some features, such as robustBufferAccess, may incur a run-time performance cost. Application writers should carefully cons= ider the implications of enabling all supported features.

To query supported features defined by the core or extensions, call:

void vkGetPhysicalDeviceFeatures2(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceFeatures2*                  pFeatures);

or the equivalent command

void vkGetPhysicalDeviceFeatures2KHR(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceFeatures2*                  pFeatures);
  • physicalDevice is the physical device from which to query t= he supported features.

  • pFeatures is a pointer to a VkPh= ysicalDeviceFeatures2 structure in which the physical device features are returned.

Each structure in pFeatures and its pNext chai= n contain members corresponding to fine-grained features. vkGetPhysicalDeviceFeatures2 writes each member to a boolean v= alue indicating whether that feature is supported.

Valid Usage (Implicit)

The VkPhysicalDeviceFeatures2 structure is defined as:

typedef struct VkPhysicalDevice=
Features2 {
    VkStructureType             sType;
    void*                       pNext;
    VkPhysicalDeviceFeatures    features;
} VkPhysicalDeviceFeatures2;

or the equivalent

typedef VkPhysicalDeviceFeatures2 VkPhysicalDeviceFeatures2KHR=
;

The VkPhysicalDeviceFeatures2 structure is defined as:

  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • features is a structure of type V= kPhysicalDeviceFeatures describing the fine-grained features of the Vulkan 1.0 API.

The pNext chain of this structure is used to extend the str= ucture with features defined by extensions. This structure can be used in vkGetPhysicalDeviceFeatures2 or can be in the pNext chain of a VkDeviceCreateInfo= structure, in which case it controls which features are enabled in the device in lieu of pEnabledFeatures.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PHYS= ICAL_DEVICE_FEATURES_2

The VkPhysicalDeviceFeatures structure is defined as:

typedef struct VkPhysicalDevice=
Features {
    VkBool32    robustBufferAccess;
    VkBool32    fullDrawIndexUint32;
    VkBool32    imageCubeArray;
    VkBool32    independentBlend;
    VkBool32    geometryShader;
    VkBool32    tessellationShader;
    VkBool32    sampleRateShading;
    VkBool32    dualSrcBlend;
    VkBool32    logicOp;
    VkBool32    multiDrawIndirect;
    VkBool32    drawIndirectFirstInstance;
    VkBool32    depthClamp;
    VkBool32    depthBiasClamp;
    VkBool32    fillModeNonSolid;
    VkBool32    depthBounds;
    VkBool32    wideLines;
    VkBool32    largePoints;
    VkBool32    alphaToOne;
    VkBool32    multiViewport;
    VkBool32    samplerAnisotropy;
    VkBool32    textureCompressionETC2;
    VkBool32    textureCompressionASTC_LDR;
    VkBool32    textureCompressionBC;
    VkBool32    occlusionQueryPrecise;
    VkBool32    pipelineStatisticsQuery;
    VkBool32    vertexPipelineStoresAndAtomics;
    VkBool32    fragmentStoresAndAtomics;
    VkBool32    shaderTessellationAndGeometryPointSize;
    VkBool32    shaderImageGatherExtended;
    VkBool32    shaderStorageImageExtendedFormats;
    VkBool32    shaderStorageImageMultisample;
    VkBool32    shaderStorageImageReadWithoutFormat;
    VkBool32    shaderStorageImageWriteWithoutFormat;
    VkBool32    shaderUniformBufferArrayDynamicIndexing;
    VkBool32    shaderSampledImageArrayDynamicIndexing;
    VkBool32    shaderStorageBufferArrayDynamicIndexing;
    VkBool32    shaderStorageImageArrayDynamicIndexing;
    VkBool32    shaderClipDistance;
    VkBool32    shaderCullDistance;
    VkBool32    shaderFloat64;
    VkBool32    shaderInt64;
    VkBool32    shaderInt16;
    VkBool32    shaderResourceResidency;
    VkBool32    shaderResourceMinLod;
    VkBool32    sparseBinding;
    VkBool32    sparseResidencyBuffer;
    VkBool32    sparseResidencyImage2D;
    VkBool32    sparseResidencyImage3D;
    VkBool32    sparseResidency2Samples;
    VkBool32    sparseResidency4Samples;
    VkBool32    sparseResidency8Samples;
    VkBool32    sparseResidency16Samples;
    VkBool32    sparseResidencyAliased;
    VkBool32    variableMultisampleRate;
    VkBool32    inheritedQueries;
} VkPhysicalDeviceFeatures;

The members of the VkPhysicalDeviceFeatures structure descr= ibe the following features:

  • robustBufferAc= cess specifies that accesses to buffers are bounds-checked against the range of the buffer descriptor (as determined by VkDescriptorBufferInfo::range, VkBufferViewCreateInfo::range, or the size of the= buffer). Out of bounds accesses must not cause app= lication termination, and the effects of shader loads, stores, and atomics must<= /strong> conform to an implementation-dependent behavior as described below.

    • A buffer access is considered to be out of bounds if any of the following are true:

      • The pointer was formed by OpImageTexelPointer and the coord= inate is less than zero or greater than or equal to the number of whole elements in the bound range.

      • The pointer was not formed by OpImageTexelPointer and the o= bject pointed to is not wholly contained within the bound range. This includes accesses performed via variable pointers where the buffer descriptor being accessed cannot be statically determined. Uninitialized pointers and pointers equal to OpConstantNull ar= e treated as pointing to a zero-sized object, so all accesses through such pointers are considered to be out of bounds.

        Note

        If a SPIR-V OpLoad instruction loads a structure and the ta= il end of the structure is out of bounds, then all members of the structure are considered out of bounds even if the members at the end are not statically used.

      • If any buffer access in a given SPIR-V block is determined to be out of bounds, then any other access of the same type (load, store, or atomic) in the same SPIR-V block that accesses an address less than 16 bytes away from the out of bounds address may also be considered out of bounds.

    • Out-of-bounds buffer loads will return any of the following values:

      • Values from anywhere within the memory range(s) bound to the buffer (possibly including bytes of memory past the end of the buffer, up to the end of the bound range).

      • Zero values, or (0,0,0,x) vectors for vector r= eads where x is a valid value represented in the type of the vector components and may be any of:

        • 0, 1, or the maximum representable positive integer value, for signed or unsigned integer components

        • 0.0 or 1.0, for floating-point components

    • Out-of-bounds writes may modify values= within the memory range(s) bound to the buffer, but must not modify = any other memory.

    • Out-of-bounds atomics may modify value= s within the memory range(s) bound to the buffer, but must not modify = any other memory, and return an undefined value.

    • Vertex input attributes are considered out of bounds if the offset of the attribute in the bound vertex buffer range plus the size of the attribute is greater than either:

      • vertexBufferRangeSize, if bindingS= tride =3D=3D 0; or

      • (vertexBufferRangeSize - (vertexBu= fferRangeSize % bindingStride))

      where vertexBufferRangeSize is the byte size of the memory = range bound to the vertex buffer binding and bindingStride is the byte str= ide of the corresponding vertex input binding. Further, if any vertex input attribute using a specific vertex input bindin= g is out of bounds, then all vertex input attributes using that vertex input binding for that vertex shader invocation are considered out of bounds.

      • If a vertex input attribute is out of bounds, it will be assigned one of the following values:

        • Values from anywhere within the memory range(s) bound to the buffer, converted according to the format of the attribute.

        • Zero values, format converted according to the format of the attribute.

        • Zero values, or (0,0,0,x) vectors, as describe= d above.

    • If robustBufferAccess is not enabled, out of bounds accesse= s may corrupt any memory within the process and cause undefined behavior up to and including application termination.

  • fullDrawIndex= Uint32 specifies the full 32-bit range of indices is supported for indexed draw calls when using a VkIndexType of VK_INDEX_TYPE_UINT= 32. maxDrawIndexedIndexValue is the maximum index value that may be used (aside from the primitive restart index, which is always 232-1 when the VkIndexType is VK_INDEX_TYPE_UINT32)= . If this feature is supported, maxDrawIndexedIndexValue must be 232-1; otherwise it must be no= smaller than 224-1. See maxDrawIndexedIndexValue.

  • imageCubeArray specifies whether image views with a VkImageViewType of VK_IMAGE_VIEW_TYPE_CUBE_ARRAY can be created, and that the corresponding SampledCubeArray and ImageCubeArray= SPIR-V capabilities can be used in shader code.<= /p>

  • independentBlend= specifies whether the VkPipelineColorBlendAttachmentState settings are controlled independently per-attachment. If this feature is not enabled, the VkPipelineColorBlendAttachmentState settings for all color attachments must be identical. Otherwise, a different VkPipelineColorBlendAttachmentState can be provided for each bound color attachment.

  • geometryShader specifies whether geometry shaders are supported. If this feature is not enabled, the VK_SHADER_STAGE_GEOMETRY_BIT and VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT enum values must not be used. This also specifies whether shader modules can declare the Geometry capability.

  • tessellationSh= ader specifies whether tessellation control and evaluation shaders are supported. If this feature is not enabled, the VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, and VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO enum values must not be used. This also specifies whether shader modules can declare the Tessellation capability.

  • sampleRateShadi= ng specifies whether Sample Shading and multisample interpolation are supported. If this feature is not enabled, the sampleShadingEnable member= of the VkPipelineMultisampleStateCreateInfo structure must be set to VK_FALSE and the minSampleShading member is ignor= ed. This also specifies whether shader modules can declare the SampleRateShading capability.

  • dualSrcBlend = specifies whether blend operations which take two sources are supported. If this feature is not enabled, the VK_BLEND_FACTOR_SRC1_COLOR= , VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, and VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA enum values must not be used as source or destination blending factors. See Dual-Source Blending.

  • logicOp specifies = whether logic operations are supported. If this feature is not enabled, the logicOpEnable member of th= e VkPipelineColorBlendStateCreateInfo structure must be set to VK_FALSE, and the logicOp member is ignored.

  • multiDrawIndire= ct specifies whether multiple draw indirect is supported. If this feature is not enabled, the drawCount parameter to the vkCmdDrawIndirect and vkCmdDrawIndexedIndirect co= mmands must be 0 or 1. The maxDrawIndirectCount member of the VkPhysicalDeviceLimits structure must= also be 1 if this feature is not supported. See maxDrawIndirectCount.

  • drawIndirectFirstInstance specifies whether indirect draw call= s support the firstInstance parameter. If this feature is not enabled, the firstInstance member of al= l VkDrawIndirectCommand and VkDrawIndexedIndirectCommand structures that are provided to the vkCmdDrawIndirect and vkCmdDrawIndexedIndirect commands mus= t be 0.

  • depthClamp spec= ifies whether depth clamping is supported. If this feature is not enabled, the depthClampEnable member of= the VkPipelineRasterizationStateCreateInfo structure must be set to VK_FALSE. Otherwise, setting depthClampEnable to VK_TRUE wi= ll enable depth clamping.

  • depthBiasClamp specifies whether depth bias clamping is supported. If this feature is not enabled, the depthBiasClamp member of t= he VkPipelineRasterizationStateCreateInfo structure must be set to 0.0 unless the VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state is enabled, and the depthBiasClamp parameter to vkCmdSetDepthBias must be se= t to 0.0.

  • fillModeNonSolid= specifies whether point and wireframe fill modes are supported. If this feature is not enabled, the VK_POLYGON_MODE_POINT and VK_POLYGON_MODE_LINE enum values must= not be used.

  • depthBounds sp= ecifies whether depth bounds tests are supported. If this feature is not enabled, the depthBoundsTestEnable memb= er of the VkPipelineDepthStencilStateCreateInfo structure must be set to VK_FALSE. When depthBoundsTestEnable is set to VK_FALSE, th= e minDepthBounds and maxDepthBounds members of the VkPipelineDepthStencilStateCreateInfo structure are ignored.

  • wideLines specif= ies whether lines with width other than 1.0 are supported. If this feature is not enabled, the lineWidth member of the VkPipelineRasterizationStateCreateInfo structure must be set to 1.0 unless the VK_DYNAMIC_STATE_LINE_WIDTH dynamic state is enabled, and the lineWidth parameter to vkCmdSetLineWidt= h must be set to 1.0. When this feature is supported, the range and granularity of supported line widths are indicated by the lineWidthRange and lineWidthGranularity members of the VkPhysicalDeviceLimi= ts structure, respectively.

  • largePoints sp= ecifies whether points with size greater than 1.0 are supported. If this feature is not enabled, only a point size of 1.0 written by a shader is supported. The range and granularity of supported point sizes are indicated by the pointSizeRange and pointSizeGranularity members o= f the VkPhysicalDeviceLimits structure, respectively.

  • alphaToOne spec= ifies whether the implementation is able to replace the alpha value of the color fragment output from the fragment shader with the maximum representable alpha value for fixed-point colors or 1.0 for floating-point colors. If this feature is not enabled, then the alphaToOneEnable memb= er of the VkPipelineMultisampleStateCreateInfo structure must be set to VK_FALSE. Otherwise setting alphaToOneEnable to VK_TRUE wil= l enable alpha-to-one behavior.

  • multiViewport specifies whether more than one viewport is supported. If this feature is not enabled, the viewportCount and scissorCount members of the VkPipelineViewportStateCreateInfo structure must be set to 1. Similarly, the viewportCount parameter to the vkCmdSetViewport command and the scissorCount par= ameter to the vkCmdSetScissor command must be 1, and the firstViewport parameter to the vkCmdSetViewport c= ommand and the firstScissor parameter to the vkCmdSetScissor= command must be 0.

  • samplerAnisotro= py specifies whether anisotropic filtering is supported. If this feature is not enabled, the anisotropyEnable member of= the VkSamplerCreateInfo structure must be VK_FALSE.

  • textureCompressionETC2 specifies whether all of the ETC2 and E= AC compressed texture formats are supported. If this feature is enabled, then the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_BLIT_SRC_BIT and VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT features must be supported in optimalTilingFeatures for the following format= s:

    • VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK

    • VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK

    • VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK

    • VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK

    • VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK

    • VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK

    • VK_FORMAT_EAC_R11_UNORM_BLOCK

    • VK_FORMAT_EAC_R11_SNORM_BLOCK

    • VK_FORMAT_EAC_R11G11_UNORM_BLOCK

    • VK_FORMAT_EAC_R11G11_SNORM_BLOCK

    vkGetPhysicalDeviceFormatProperties= and vkGetPhysicalDeviceImageFormatPro= perties can be used to check for additional supported properties of individual formats.

  • textureCompressionASTC_LDR specifies whether all of the ASTC L= DR compressed texture formats are supported. If this feature is enabled, then the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_BLIT_SRC_BIT and VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT features must be supported in optimalTilingFeatures for the following format= s:

    • VK_FORMAT_ASTC_4x4_UNORM_BLOCK

    • VK_FORMAT_ASTC_4x4_SRGB_BLOCK

    • VK_FORMAT_ASTC_5x4_UNORM_BLOCK

    • VK_FORMAT_ASTC_5x4_SRGB_BLOCK

    • VK_FORMAT_ASTC_5x5_UNORM_BLOCK

    • VK_FORMAT_ASTC_5x5_SRGB_BLOCK

    • VK_FORMAT_ASTC_6x5_UNORM_BLOCK

    • VK_FORMAT_ASTC_6x5_SRGB_BLOCK

    • VK_FORMAT_ASTC_6x6_UNORM_BLOCK

    • VK_FORMAT_ASTC_6x6_SRGB_BLOCK

    • VK_FORMAT_ASTC_8x5_UNORM_BLOCK

    • VK_FORMAT_ASTC_8x5_SRGB_BLOCK

    • VK_FORMAT_ASTC_8x6_UNORM_BLOCK

    • VK_FORMAT_ASTC_8x6_SRGB_BLOCK

    • VK_FORMAT_ASTC_8x8_UNORM_BLOCK

    • VK_FORMAT_ASTC_8x8_SRGB_BLOCK

    • VK_FORMAT_ASTC_10x5_UNORM_BLOCK

    • VK_FORMAT_ASTC_10x5_SRGB_BLOCK

    • VK_FORMAT_ASTC_10x6_UNORM_BLOCK

    • VK_FORMAT_ASTC_10x6_SRGB_BLOCK

    • VK_FORMAT_ASTC_10x8_UNORM_BLOCK

    • VK_FORMAT_ASTC_10x8_SRGB_BLOCK

    • VK_FORMAT_ASTC_10x10_UNORM_BLOCK

    • VK_FORMAT_ASTC_10x10_SRGB_BLOCK

    • VK_FORMAT_ASTC_12x10_UNORM_BLOCK

    • VK_FORMAT_ASTC_12x10_SRGB_BLOCK

    • VK_FORMAT_ASTC_12x12_UNORM_BLOCK

    • VK_FORMAT_ASTC_12x12_SRGB_BLOCK

    vkGetPhysicalDeviceFormatProperties= and vkGetPhysicalDeviceImageFormatPro= perties can be used to check for additional supported properties of individual formats.

  • textureCompr= essionBC specifies whether all of the BC compressed texture formats are supported. If this feature is enabled, then the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_BLIT_SRC_BIT and VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT features must be supported in optimalTilingFeatures for the following format= s:

    • VK_FORMAT_BC1_RGB_UNORM_BLOCK

    • VK_FORMAT_BC1_RGB_SRGB_BLOCK

    • VK_FORMAT_BC1_RGBA_UNORM_BLOCK

    • VK_FORMAT_BC1_RGBA_SRGB_BLOCK

    • VK_FORMAT_BC2_UNORM_BLOCK

    • VK_FORMAT_BC2_SRGB_BLOCK

    • VK_FORMAT_BC3_UNORM_BLOCK

    • VK_FORMAT_BC3_SRGB_BLOCK

    • VK_FORMAT_BC4_UNORM_BLOCK

    • VK_FORMAT_BC4_SNORM_BLOCK

    • VK_FORMAT_BC5_UNORM_BLOCK

    • VK_FORMAT_BC5_SNORM_BLOCK

    • VK_FORMAT_BC6H_UFLOAT_BLOCK

    • VK_FORMAT_BC6H_SFLOAT_BLOCK

    • VK_FORMAT_BC7_UNORM_BLOCK

    • VK_FORMAT_BC7_SRGB_BLOCK

    vkGetPhysicalDeviceFormatProperties= and vkGetPhysicalDeviceImageFormatPro= perties can be used to check for additional supported properties of individual formats.

  • occlusionQu= eryPrecise specifies whether occlusion queries returning actual sample counts are supported. Occlusion queries are created in a VkQueryPool by specifying t= he queryType of VK_QUERY_TYPE_OCCLUSION in the VkQueryPoolCreateInfo structure which is passed to vkCreateQueryPool. If this feature is enabled, queries of this type c= an enable VK_QUERY_CONTROL_PRECISE_BIT in the flags paramet= er to vkCmdBeginQuery. If this feature is not supported, the implementation supports only boolean occlusion queries. When any samples are passed, boolean queries will return a non-zero result value, otherwise a result value of zero is returned. When this feature is enabled and VK_QUERY_CONTROL_PRECISE_BIT = is set, occlusion queries will report the actual number of samples passed.

  • pipelineStatisticsQuery specifies whether the pipeline statist= ics queries are supported. If this feature is not enabled, queries of type VK_QUERY_TYPE_PIPELINE_STATISTICS can= not be created, and none of the VkQueryPipelineStatisticFlagBits = bits can be set in the pipelineStatistics member of the VkQueryPoolCreateInfo structure.

  • vertexPipelineStoresAndAtomics specifies whether storage buffe= rs and images support stores and atomic operations in the vertex, tessellation, and geometry shader stages. If this feature is not enabled, all storage image, storage texel buffers, and storage buffer variables used by these stages in shader modules must be decorated with the = NonWritable decoration (or the readonly memory qualifier in GLSL).

  • fragmentStoresAndAtomics specifies whether storage buffers and images support stores and atomic operations in the fragment shader stage. If this feature is not enabled, all storage image, storage texel buffers, and storage buffer variables used by the fragment stage in shader modules must be decorated with the= NonWritable decoration (or the readonly memory qualifier in GLSL).

  • shaderTessellationAndGeometryPointSize specifies whether the PointSize built-in decoration is available in the tessellation control, tessellation evaluation, and geometry shader stages. If this feature is not enabled, members decorated with the PointSize built-in decoration must not be read from or written to and all points written from a tessellation or geometry shader will have a size of 1.0. This also specifies whether shader modules can declare the TessellationPointSize capability for tessellation control and evaluation shaders, or if the shader modules can declare the GeometryPointSize capability for geometry shaders. An implementation supporting this feature must also support one or both of the tessellationShader or geometryShader featur= es.

  • shaderImageGatherExtended specifies whether the extended set o= f image gather instructions are available in shader code. If this feature is not enabled, the OpImage*Gather instructions do not support the Offset and ConstOffsets<= /code> operands. This also specifies whether shader modules can declare the ImageGatherExtended capability.

  • shaderStorageImageExtendedFormats specifies whether the extend= ed storage image formats are available in shader code. If this feature is not enabled, the formats requiring the StorageImageExtendedFormats capability are not supported for storage images. This also specifies whether shader modules can declare the StorageImageExtendedFormats capability.

  • shaderStorageImageMultisample specifies whether multisampled storage images are supported. If this feature is not enabled, images that are created with a usage that includes VK_IMAGE_USAGE_STORAGE_BIT must be created with samples equal to VK_SAMPLE_COUNT_1_BIT. This also specifies whether shader modules can declare the StorageImageMultisample capability.

  • shaderStorageImageReadWithoutFormat specifies whether storage images require a format qualifier to be specified when reading from storage images. If this feature is not enabled, the OpImageRead instruction must not have an OpTypeImage of Unknown. This also specifies whether shader modules can declare the StorageImageReadWithoutFormat capability.

  • shaderStorageImageWriteWithoutFormat specifies whether storage images require a format qualifier to be specified when writing to storage images. If this feature is not enabled, the OpImageWrite instruction <= strong class=3D"purple">must not have an OpTypeImage of Unknown. This also specifies whether shader modules can declare the StorageImageWriteWithoutFormat capability.

  • shaderUniformBufferArrayDynamicIndexing specifies whether arra= ys of uniform buffers can be indexed by = dynamically uniform integer expressions in shader code. If this feature is not enabled, resources with a descriptor type of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC must be indexed only by constant integral expressions when aggregated into arrays in shader code. This also specifies whether shader modules can declare the UniformBufferArrayDynamicIndexing capability.

  • shaderSampledImageArrayDynamicIndexing specifies whether array= s of samplers or sampled images can be indexed= by dynamically uniform integer expressions in shader code. If this feature is not enabled, resources with a descriptor type of VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, or VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE must= be indexed only by constant integral expressions when aggregated into arrays in shader code. This also specifies whether shader modules can declare the SampledImageArrayDynamicIndexing capability.

  • shaderStorageBufferArrayDynamicIndexing specifies whether arra= ys of storage buffers can be indexed by dyna= mically uniform integer expressions in shader code. If this feature is not enabled, resources with a descriptor type of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC must be indexed only by constant integral expressions when aggregated into arrays in shader code. This also specifies whether shader modules can declare the StorageBufferArrayDynamicIndexing capability.

  • shaderStorageImageArrayDynamicIndexing specifies whether array= s of storage images can be indexed by dynamica= lly uniform integer expressions in shader code. If this feature is not enabled, resources with a descriptor type of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE must= be indexed only by constant integral expressions when aggregated into arrays in shader code. This also specifies whether shader modules can declare the StorageImageArrayDynamicIndexing capability.

  • shaderClipDist= ance specifies whether clip distances are supported in shader code. If this feature is not enabled, any members decorated with the ClipDistance built-in decoration must= not be read from or written to in shader modules. This also specifies whether shader modules can declare the ClipDistance capability.

  • shaderCullDist= ance specifies whether cull distances are supported in shader code. If this feature is not enabled, any members decorated with the CullDistance built-in decoration must= not be read from or written to in shader modules. This also specifies whether shader modules can declare the CullDistance capability.

  • shaderFloat64 specifies whether 64-bit floats (doubles) are supported in shader code. If this feature is not enabled, 64-bit floating-point types must not be used in shader code. This also specifies whether shader modules can declare the Float64 capability.

  • shaderInt64 sp= ecifies whether 64-bit integers (signed and unsigned) are supported in shader code. If this feature is not enabled, 64-bit integer types must not be used in shader code. This also specifies whether shader modules can declare the Int64 capability.

  • shaderInt16 sp= ecifies whether 16-bit integers (signed and unsigned) are supported in shader code. If this feature is not enabled, 16-bit integer types must not be used in shader code. This also specifies whether shader modules can declare the Int16 capability.

  • shaderResourceResidency specifies whether image operations tha= t return resource residency information are supported in shader code. If this feature is not enabled, the OpImageSparse* instruction= s must not be used in shader code. This also specifies whether shader modules can declare the SparseResidency capability. The feature requires at least one of the sparseResidency* feat= ures to be supported.

  • shaderResour= ceMinLod specifies whether image operations that specify the minimum resource LOD are supported in shader code. If this feature is not enabled, the MinLod image operand must not be used in shader code. This also specifies whether shader modules can declare the MinLod capability.

  • sparseBinding specifies whether resource memory can be managed at= opaque sparse block level instead of at the object level. If this feature is not enabled, resource memory mu= st be bound only on a per-object basis using the vkBindBufferMemory and vkBindImageMemory commands. In this case, buffers and images must not= be created with VK_BUFFER_CREATE_SPARSE_BINDING_BIT and VK_IMAGE_CREATE_SPARSE_BINDING_BIT set in the flags member of the VkBufferCreateInfo and VkImageCreateInfo s= tructures, respectively. Otherwise resource memory can be managed = as described in Sparse Resource Features.

  • sparseResid= encyBuffer specifies whether the device can access p= artially resident buffers. If this feature is not enabled, buffers must not be created with VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT set in the flags member of the VkBufferCreateInfo structure.

  • sparseResidencyImage2D specifies whether the device can access partially resident 2D images with 1 sample per pixel. If this feature is not enabled, images with an imageType of VK_IMAGE_TYPE_2D and samples set to VK_SAMPLE_COUNT_1_BIT must n= ot be created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set in the flags member of the VkImageCreateInfo structure.

  • sparseResidencyImage3D specifies whether the device can access partially resident 3D images. If this feature is not enabled, images with an imageType of VK_IMAGE_TYPE_3D must not be= created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set in the flags member of the VkImageCreateInfo structure.

  • sparseResidency2Samples specifies whether the physical device = can access partially resident 2D images with 2 samples per pixel. If this feature is not enabled, images with an imageType of VK_IMAGE_TYPE_2D and samples set to VK_SAMPLE_COUNT_2_BIT must n= ot be created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set in the flags member of the VkImageCreateInfo structure.

  • sparseResidency4Samples specifies whether the physical device = can access partially resident 2D images with 4 samples per pixel. If this feature is not enabled, images with an imageType of VK_IMAGE_TYPE_2D and samples set to VK_SAMPLE_COUNT_4_BIT must n= ot be created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set in the flags member of the VkImageCreateInfo structure.

  • sparseResidency8Samples specifies whether the physical device = can access partially resident 2D images with 8 samples per pixel. If this feature is not enabled, images with an imageType of VK_IMAGE_TYPE_2D and samples set to VK_SAMPLE_COUNT_8_BIT must n= ot be created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set in the flags member of the VkImageCreateInfo structure.

  • sparseResidency16Samples specifies whether the physical device can access partially resident 2D images w= ith 16 samples per pixel. If this feature is not enabled, images with an imageType of VK_IMAGE_TYPE_2D and samples set to VK_SAMPLE_COUNT_16_BIT must = not be created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set in the flags member of the VkImageCreateInfo structure.

  • sparseResidencyAliased specifies whether the physical device <= strong class=3D"purple">can correctly access data aliased into multiple locations. If this feature is not enabled, the VK_BUFFER_CREATE_SPARSE_ALIASED_BIT and VK_IMAGE_CREATE_SPARSE_ALIASED_BIT enum values must not be used in flags members of the VkBufferCreateInfo and VkImageCreateInfo structures, respectively.

  • variableMultisampleRate specifies whether all pipelines that w= ill be bound to a command buffer during a subpass with no attachments must have the same value for VkPipelineMultisampleStateCreateInfo::rasterizationSampl= es. If set to VK_TRUE, the implementation supports variable multisample rates in a subpass with no attachments. If set to VK_FALSE, then all pipelines bound in such a subpass must have the same multisample rate. This has no effect in situations where a subpass uses any attachments.

  • inheritedQueries= specifies whether a secondary command buffer may be= executed while a query is active.

The VkPhysicalDeviceVariablePointerFeatures structure is de= fined as:

typedef struct VkPhysicalDevice=
VariablePointerFeatures {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           variablePointersStorageBuffer;
    VkBool32           variablePointers;
} VkPhysicalDeviceVariablePointerFeatures;

or the equivalent

typedef VkPhysicalDeviceVariablePointerFeatures VkPhysicalDevi=
ceVariablePointerFeaturesKHR;

The members of the VkPhysicalDeviceVariablePointerFeatures = structure describe the following features:

  • variablePointersStorageBuffer specifies whether the implementa= tion supports the SPIR-V VariablePointersStorageBuffer capability. When this feature is not enabled, shader modules m= ust not declare the SPV_KHR_variable_pointers extension or the VariablePointersStorageBuffer capability.

  • variablePointers= specifies whether the implementation supports the SPIR-V VariablePointers capability. When this feature is not enabled, shader modules m= ust not declare the VariablePointers capability.

If the VkPhysicalDeviceVariablePointerFeatures structure is= included in the pNext chain of VkPhysicalDev= iceFeatures2, it is filled with values indicating whether each feature is supported. VkPhysicalDeviceVariablePointerFeatures can also be used in the pNext chain of VkDeviceCreateInfo to e= nable the features.

Valid Usage
  • If variablePointers is enabled then variablePointersStorageBuffer must also be enabled.

Valid Usage (Implicit)
  • = sType must be VK_STRUC= TURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES

The VkPhysicalDeviceMultiviewFeatures structure is defined = as:

typedef struct VkPhysicalDevice=
MultiviewFeatures {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           multiview;
    VkBool32           multiviewGeometryShader;
    VkBool32           multiviewTessellationShader;
} VkPhysicalDeviceMultiviewFeatures;

or the equivalent

typedef VkPhysicalDeviceMultiviewFeatures VkPhysicalDeviceMult=
iviewFeaturesKHR;

The members of the VkPhysicalDeviceMultiviewFeatures struct= ure describe the following features:

  • multiview specif= ies whether the implementation supports multiview rendering within a render pass. If this feature is not enabled, the view mask of each subpass must always be zero.

  • multiviewGeometrySha= der specifies whether the implementation supports multiview rendering within a render pass, with geometry shaders. If this feature is not enabled, then a pipeline compiled against a subpass with a non-zero view mask must no= t include a geometry shader.

  • multiviewTessellat= ionShader specifies whether the implementation supports multiview rendering within a render pass, with tessellation shaders. If this feature is not enabled, then a pipeline compiled against a subpass with a non-zero view mask must no= t include any tessellation shaders.

If the VkPhysicalDeviceMultiviewFeatures structure is inclu= ded in the pNext chain of VkPhysicalDeviceFeat= ures2, it is filled with values indicating whether each feature is supported. VkPhysicalDeviceMultiviewFeatures can= also be used in the pNext chain of VkDeviceCreateInfo to enable the features.=

Valid Usage
  • If multiviewGeometryShader is enabled then multiview must also be enabled.

  • If multiviewTessellationShader is enabled then multiview= must also be enabled.

Valid Usage (Implicit)
  • = sType must be VK_STRUCTURE_T= YPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES

To query 8-bit storage features additionally supported call vkGetPhysicalDeviceFeatures2 with a VkPhysicalDevice8BitStorageFeaturesKHR structure included in t= he pNext chain of its pFeatures parameter. The VkPhysicalDevice8BitStorageFeaturesKHR structure can also be in the pNext chain of a VkDeviceCreateInfo structure, in which case it controls which additional features are enabled in the device.

typedef struct VkPhysicalDevice=
8BitStorageFeaturesKHR {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           storageBuffer8BitAccess;
    VkBool32           uniformAndStorageBuffer8BitAccess;
    VkBool32           storagePushConstant8;
} VkPhysicalDevice8BitStorageFeaturesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • storageBuffer8BitAccess indicates whether objects in the StorageBuffer storage class with the Block decora= tion can have 8-bit integer members. If this feature is not enabled, 8-bit integer members must not be used in such objects. This also indicates whether shader modules can declare the StorageBuffer8BitAccess capability.

  • uniformAndStorageBuffer8BitAccess indicates whether objects in the Uniform storage class with the Block decorati= on and in the StorageBuffer storage class with the same decoration can have 8-bit integer members. If this feature is not enabled, 8-bit integer members must not be used in such objects. This also indicates whether shader modules can declare the UniformAndStorageBuffer8BitAccess capability.

  • storagePushC= onstant8 indicates whether objects in the PushConstant storage class can have 8-bit integer members. If this feature is not enabled, 8-bit integer members must not be used in such objects. This also indicates whether shader modules can declare the StoragePushConstant8 capability.

Valid Usage (Implicit)
  • <= code>sType must be VK_STRUCT= URE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR

To query 16-bit storage features additionally supported call vkGetPhysicalDeviceFeatures2 with a VkPhysicalDevice16BitStorageFeatures structure included in the pNext chain of its pFeatures parameter. The VkPhysicalDevice16BitStorageFeatures structure can also be in the pNext chain of a VkDeviceCreateInfo st= ructure, in which case it controls which additional features are enabled in the device.

The VkPhysicalDevice16BitStorageFe= atures structure is defined as:

typedef struct VkPhysicalDevice=
16BitStorageFeatures {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           storageBuffer16BitAccess;
    VkBool32           uniformAndStorageBuffer16BitAccess;
    VkBool32           storagePushConstant16;
    VkBool32           storageInputOutput16;
} VkPhysicalDevice16BitStorageFeatures;

or the equivalent

typedef VkPhysicalDevice16BitStorageFeatures VkPhysicalDevice1=
6BitStorageFeaturesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • storageBuffer16BitAccess specifies whether objects in the StorageBuffer storage class with the Block decora= tion can have 16-bit integer and 16-bit floating-point members. If this feature is not enabled, 16-bit integer or 16-bit floating-point members must not be used in such objects. This also specifies whether shader modules can declare the StorageBuffer16BitAccess capability.

  • uniformAndStorageBuffer16BitAccess specifies whether objects i= n the Uniform storage class with the Block decorati= on and in the StorageBuffer storage class with the same decoration can have 16-bit integer and 16-bit floating-point members. If this feature is not enabled, 16-bit integer or 16-bit floating-point members must not be used in such objects. This also specifies whether shader modules can declare the UniformAndStorageBuffer16BitAccess capability.

  • storagePush= Constant16 specifies whether objects in the PushConstant storage class can have 16-bit integer and 16-bit floating-point members. If this feature is not enabled, 16-bit integer or floating-point members must not be used in such objects. This also specifies whether shader modules can declare the StoragePushConstant16 capability.

  • storageInput= Output16 specifies whether objects in the Input and Output= storage classes can have 16-bit integer and 16-bi= t floating-point members. If this feature is not enabled, 16-bit integer or 16-bit floating-point members must not be used in such objects. This also specifies whether shader modules can declare the StorageInputOutput16 capability.

Valid Usage (Implicit)
  • sType must be VK_STRUCTUR= E_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES

The VkPhysicalDeviceSamplerYcbcrConversionFeatures structur= e is defined as:

typedef struct VkPhysicalDevice=
SamplerYcbcrConversionFeatures {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           samplerYcbcrConversion;
} VkPhysicalDeviceSamplerYcbcrConversionFeatures;

or the equivalent

typedef VkPhysicalDeviceSamplerYcbcrConversionFeatures VkPhysi=
calDeviceSamplerYcbcrConversionFeaturesKHR;

The members of the VkPhysicalDeviceSamplerYcbcrConversionFeatures<= /code> structure describe the following feature:

  • samplerYcbcrConversion specifies whether the implementation supports sampler Y=E2=80=99CBCR<= /sub> conversion. If samplerYcbcrConversion is VK_FALSE, sampler Y= =E2=80=99CBCR conversion is not supported, and samplers using sampler Y=E2=80=99CBCR conversion must not be used.

Valid Usage (Implicit)
  • sType must be V= K_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES

The VkPhysicalDeviceProtectedMemoryFeatures structure is de= fined as:

typedef struct VkPhysicalDevice=
ProtectedMemoryFeatures {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           protectedMemory;
} VkPhysicalDeviceProtectedMemoryFeatures;
  • protectedMemory specifies whether protected memory is suppo= rted.

If the VkPhysicalDeviceProtectedMemoryFeatures structure is= included in the pNext chain of VkPhysicalDev= iceFeatures2, it is filled with a value indicating whether the feature is supported.

Valid Usage (Implicit)
  • = sType must be VK_STRUC= TURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES

The VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT struc= ture is defined as:

typedef struct VkPhysicalDevice=
BlendOperationAdvancedFeaturesEXT {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           advancedBlendCoherentOperations;
} VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT;

The members of the VkPhysicalDeviceBlendOperationAdvancedFeaturesE= XT structure describe the following features:

  • advancedBlendCoherentOperations specifies whether blending usi= ng advanced blend operations is guaranteed to execute atomically and in primitive order. If this is VK_TRUE, VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT is treated= the same as VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, and advanced blen= ding needs no additional synchronization over basic blending. If this is VK_FALSE, then memory dependencies are required to guarantee order between two advanced blending operations that occur on the same sample.

If the VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT st= ructure is included in the pNext chain of VkPh= ysicalDeviceFeatures2, it is filled with values indicating whether each feature is supported. VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT can also be used in pNext chain of VkDeviceCreateInfo to e= nable the features.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT

The VkPhysicalDeviceConditionalRenderingFeaturesEXT structu= re is defined as:

typedef struct VkPhysicalDevice=
ConditionalRenderingFeaturesEXT {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           conditionalRendering;
    VkBool32           inheritedConditionalRendering;
} VkPhysicalDeviceConditionalRenderingFeaturesEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • conditionalR= endering specifies whether conditional rendering is supported.

  • inheritedConditionalRendering specifies whether a secondary command buffer can be executed while cond= itional rendering is active in the primary command buffer.

If the VkPhysicalDeviceConditionalRenderingFeaturesEXT stru= cture is included in the pNext chain of VkPh= ysicalDeviceFeatures2, it is filled with values indicating the implementation-dependent behavior. VkPhysicalDeviceConditionalRenderingFeaturesEXT can also be used in pNext chain of VkDeviceCreateInfo to e= nable the features.

Valid Usage (Implicit)
  • sType must be = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT=

The VkPhysicalDeviceShaderDrawParameterFeatures structure i= s defined as:

typedef struct VkPhysicalDevice=
ShaderDrawParameterFeatures {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           shaderDrawParameters;
} VkPhysicalDeviceShaderDrawParameterFeatures;
  • shaderDrawPa= rameters specifies whether shader draw parameters are supported.

If the VkPhysicalDeviceShaderDrawParameterFeatures structur= e is included in the pNext chain of VkPh= ysicalDeviceFeatures2, it is filled with a value indicating whether the feature is supported.

The VkPhysicalDeviceDescriptorIndexingFeaturesEXT structure= is defined as:

typedef struct VkPhysicalDevice=
DescriptorIndexingFeaturesEXT {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           shaderInputAttachmentArrayDynamicIndexing;
    VkBool32           shaderUniformTexelBufferArrayDynamicIndexing;
    VkBool32           shaderStorageTexelBufferArrayDynamicIndexing;
    VkBool32           shaderUniformBufferArrayNonUniformIndexing;
    VkBool32           shaderSampledImageArrayNonUniformIndexing;
    VkBool32           shaderStorageBufferArrayNonUniformIndexing;
    VkBool32           shaderStorageImageArrayNonUniformIndexing;
    VkBool32           shaderInputAttachmentArrayNonUniformIndexing;
    VkBool32           shaderUniformTexelBufferArrayNonUniformIndexing;
    VkBool32           shaderStorageTexelBufferArrayNonUniformIndexing;
    VkBool32           descriptorBindingUniformBufferUpdateAfterBind;
    VkBool32           descriptorBindingSampledImageUpdateAfterBind;
    VkBool32           descriptorBindingStorageImageUpdateAfterBind;
    VkBool32           descriptorBindingStorageBufferUpdateAfterBind;
    VkBool32           descriptorBindingUniformTexelBufferUpdateAfterBind;
    VkBool32           descriptorBindingStorageTexelBufferUpdateAfterBind;
    VkBool32           descriptorBindingUpdateUnusedWhilePending;
    VkBool32           descriptorBindingPartiallyBound;
    VkBool32           descriptorBindingVariableDescriptorCount;
    VkBool32           runtimeDescriptorArray;
} VkPhysicalDeviceDescriptorIndexingFeaturesEXT;

The members of the VkPhysicalDeviceDescriptorIndexingFeaturesEXT structure describe the following features:

If the VkPhysicalDeviceDescriptorIndexingFeaturesEXT struct= ure is included in the pNext chain of V= kPhysicalDeviceFeatures2KHR, it is filled with values indicating whether each feature is supported. VkPhysicalDeviceDescriptorIndexingFeaturesEXT can also be used in the pNext chain of VkDeviceCreateInfo to e= nable features.

Valid Usage (Implicit)
  • sType must be VK= _STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT

32.2. Limits

There are a variety of implementation-dependent limits.

The VkPhysicalDeviceLimits are properties of the physical d= evice. These are available in the limits member of the VkPhysicalDeviceProperties structure which = is returned from vkGetPhysicalDeviceProperties.

The VkPhysicalDeviceLimits structure is defined as:

typedef struct VkPhysicalDevice=
Limits {
    uint32_t              maxImageDimension1D;
    uint32_t              maxImageDimension2D;
    uint32_t              maxImageDimension3D;
    uint32_t              maxImageDimensionCube;
    uint32_t              maxImageArrayLayers;
    uint32_t              maxTexelBufferElements;
    uint32_t              maxUniformBufferRange;
    uint32_t              maxStorageBufferRange;
    uint32_t              maxPushConstantsSize;
    uint32_t              maxMemoryAllocationCount;
    uint32_t              maxSamplerAllocationCount;
    VkDeviceSize          bufferImageGranularity;
    VkDeviceSize          sparseAddressSpaceSize;
    uint32_t              maxBoundDescriptorSets;
    uint32_t              maxPerStageDescriptorSamplers;
    uint32_t              maxPerStageDescriptorUniformBuffers;
    uint32_t              maxPerStageDescriptorStorageBuffers;
    uint32_t              maxPerStageDescriptorSampledImages;
    uint32_t              maxPerStageDescriptorStorageImages;
    uint32_t              maxPerStageDescriptorInputAttachments;
    uint32_t              maxPerStageResources;
    uint32_t              maxDescriptorSetSamplers;
    uint32_t              maxDescriptorSetUniformBuffers;
    uint32_t              maxDescriptorSetUniformBuffersDynamic;
    uint32_t              maxDescriptorSetStorageBuffers;
    uint32_t              maxDescriptorSetStorageBuffersDynamic;
    uint32_t              maxDescriptorSetSampledImages;
    uint32_t              maxDescriptorSetStorageImages;
    uint32_t              maxDescriptorSetInputAttachments;
    uint32_t              maxVertexInputAttributes;
    uint32_t              maxVertexInputBindings;
    uint32_t              maxVertexInputAttributeOffset;
    uint32_t              maxVertexInputBindingStride;
    uint32_t              maxVertexOutputComponents;
    uint32_t              maxTessellationGenerationLevel;
    uint32_t              maxTessellationPatchSize;
    uint32_t              maxTessellationControlPerVertexInputComponents;
    uint32_t              maxTessellationControlPerVertexOutputComponents;
    uint32_t              maxTessellationControlPerPatchOutputComponents;
    uint32_t              maxTessellationControlTotalOutputComponents;
    uint32_t              maxTessellationEvaluationInputComponents;
    uint32_t              maxTessellationEvaluationOutputComponents;
    uint32_t              maxGeometryShaderInvocations;
    uint32_t              maxGeometryInputComponents;
    uint32_t              maxGeometryOutputComponents;
    uint32_t              maxGeometryOutputVertices;
    uint32_t              maxGeometryTotalOutputComponents;
    uint32_t              maxFragmentInputComponents;
    uint32_t              maxFragmentOutputAttachments;
    uint32_t              maxFragmentDualSrcAttachments;
    uint32_t              maxFragmentCombinedOutputResources;
    uint32_t              maxComputeSharedMemorySize;
    uint32_t              maxComputeWorkGroupCount[=
3];
    uint32_t              maxComputeWorkGroupInvocations;
    uint32_t              maxComputeWorkGroupSize[3=
];
    uint32_t              subPixelPrecisionBits;
    uint32_t              subTexelPrecisionBits;
    uint32_t              mipmapPrecisionBits;
    uint32_t              maxDrawIndexedIndexValue;
    uint32_t              maxDrawIndirectCount;
    float                 maxSampler=
LodBias;
    float                 maxSampler=
Anisotropy;
    uint32_t              maxViewports;
    uint32_t              maxViewportDimensions[2];
    float                 viewportBo=
undsRange[2];
    uint32_t              viewportSubPixelBits;
    size_t                minMemoryMapAlignment;
    VkDeviceSize          minTexelBufferOffsetAlignment;
    VkDeviceSize          minUniformBufferOffsetAlignment;
    VkDeviceSize          minStorageBufferOffsetAlignment;
    int32_t               minTexelOffset;
    uint32_t              maxTexelOffset;
    int32_t               minTexelGatherOffset;
    uint32_t              maxTexelGatherOffset;
    float                 minInterpo=
lationOffset;
    float                 maxInterpo=
lationOffset;
    uint32_t              subPixelInterpolationOffsetBits;
    uint32_t              maxFramebufferWidth;
    uint32_t              maxFramebufferHeight;
    uint32_t              maxFramebufferLayers;
    VkSampleCountFlags    framebufferColorSampleCounts;
    VkSampleCountFlags    framebufferDepthSampleCounts;
    VkSampleCountFlags    framebufferStencilSampleCounts;
    VkSampleCountFlags    framebufferNoAttachmentsSampleCounts;
    uint32_t              maxColorAttachments;
    VkSampleCountFlags    sampledImageColorSampleCounts;
    VkSampleCountFlags    sampledImageIntegerSampleCounts;
    VkSampleCountFlags    sampledImageDepthSampleCounts;
    VkSampleCountFlags    sampledImageStencilSampleCounts;
    VkSampleCountFlags    storageImageSampleCounts;
    uint32_t              maxSampleMaskWords;
    VkBool32              timestampComputeAndGraphics;
    float                 timestampP=
eriod;
    uint32_t              maxClipDistances;
    uint32_t              maxCullDistances;
    uint32_t              maxCombinedClipAndCullDistances;
    uint32_t              discreteQueuePriorities;
    float                 pointSizeR=
ange[2];
    float                 lineWidthR=
ange[2];
    float                 pointSizeG=
ranularity;
    float                 lineWidthG=
ranularity;
    VkBool32              strictLines;
    VkBool32              standardSampleLocations;
    VkDeviceSize          optimalBufferCopyOffsetAlignment;
    VkDeviceSize          optimalBufferCopyRowPitchAlignment;
    VkDeviceSize          nonCoherentAtomSize;
} VkPhysicalDeviceLimits;
  • maxImageDimensi= on1D is the maximum dimension (width) supported for all images created wit= h an imageType of VK_IMAGE_TYPE_1D.

  • maxImageDimensi= on2D is the maximum dimension (width or height) supported for= all images created with an imageType of VK_IMAGE_TYPE_2D and= without VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT set in flags.=

  • maxImageDimensi= on3D is the maximum dimension (width, height, or depth<= /code>) supported for all images created with an imageType of VK_IMAGE_TYPE_3D.

  • maxImageDimen= sionCube is the maximum dimension (width or height) supported= for all images created with an imageType of VK_IMAGE_TYPE_2D and with VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT set in flags.

  • maxImageArrayLa= yers is the maximum number of layers (arrayLayers) for an image.

  • maxTexelBuff= erElements is the maximum number of addressable texels for a buffer view created on a buffer which was created with the VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set in the usag= e member of the VkBufferCreateInfo structure.

  • maxUniformBuf= ferRange is the maximum value that can be specified i= n the range member of any VkDescriptorBufferInfo structures passed to= a call to vkUpdateDescriptorSets for descriptors of type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC.

  • maxStorageBuf= ferRange is the maximum value that can be specified i= n the range member of any VkDescriptorBufferInfo structures passed to= a call to vkUpdateDescriptorSets for descriptors of type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC.

  • maxPushConstan= tsSize is the maximum size, in bytes, of the pool of push constant memory. For each of the push constant ranges indicated by the pPushConstantRanges member of the VkPipelineLayoutCreate= Info structure, (offset + size) must be less than or equal to this limit.

  • maxMemoryAllocationCount is the maximum number of device memor= y allocations, as created by vkAllocateMemory, which can simultaneously exist.

  • maxSamplerAllocationCount is the maximum number of sampler objects, as created by vkCreateSampler, which can simultaneously exist on a device.

  • bufferImageG= ranularity is the granularity, in bytes, at which buffer or linear image resources, and optimal image resources can be bound = to adjacent offsets in the same VkDeviceMemory object without aliasing. See Buffer-Image Granularity for more details.

  • sparseAddres= sSpaceSize is the total amount of address space available, in bytes, for sparse memory resources. This is an upper bound on the sum of the size of all sparse resources, regardless of whether any memory is bound to them.

  • maxBoundDesc= riptorSets is the maximum number of descriptor sets that can<= /strong> be simultaneously used by a pipeline. All DescriptorSet decorations in shader modules must have a value less than maxBoundDescriptorSets. See Descriptor Sets.

  • maxPerStageDescriptorSamplers is the maximum number of sampler= s that can be accessible to a single shader= stage in a pipeline layout. Descriptors with a type of VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. A descriptor is accessible to a shader stage when the stageFlags member of the VkDescriptorSetLayoutBinding structure has the b= it for that shader stage set. See Sampler and Combined Image Sampler.

  • maxPerStageDescriptorUniformBuffers is the maximum number of uniform buffers that can be accessible to= a single shader stage in a pipeline layout. Descriptors with a type of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER o= r VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. A descriptor is accessible to a shader stage when the stageFlags member of the VkDescriptorSetLayoutBinding structure has the b= it for that shader stage set. See Uniform Buffer and Dynamic Uniform Buffer.

  • maxPerStageDescriptorStorageBuffers is the maximum number of storage buffers that can be accessible to= a single shader stage in a pipeline layout. Descriptors with a type of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER o= r VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. A descriptor is accessible to a pipeline shader stage when the stageFlags member of the VkDescriptorSetLayoutBinding structure has the bit for that shader stage set. See Storage Buffer and Dynamic Storage Buffer.

  • maxPerStageDescriptorSampledImages is the maximum number of sampled images that can be accessible to = a single shader stage in a pipeline layout. Descriptors with a type of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, or VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER count against this lim= it. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. A descriptor is accessible to a pipeline shader stage when the stageFlags member of the VkDescriptorSetLayoutBinding structure has the bit for that shader stage set. See Combined Image Sampler, Sampled Image, and Uniform Texel Buffer.

  • maxPerStageDescriptorStorageImages is the maximum number of storage images that can be accessible to = a single shader stage in a pipeline layout. Descriptors with a type of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, o= r VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER count against this lim= it. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. A descriptor is accessible to a pipeline shader stage when the stageFlags member of the VkDescriptorSetLayoutBinding structure has the bit for that shader stage set. See Storage Image, and Storage Texel Buffer.

  • maxPerStageDescriptorInputAttachments is the maximum number of input attachments that can be accessible = to a single shader stage in a pipeline layout. Descriptors with a type of VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. A descriptor is accessible to a pipeline shader stage when the stageFlags member of the VkDescriptorSetLayoutBinding structure has the bit for that shader stage set. These are only supported for the fragment stage. See Input Attachment.

  • maxPerStageRes= ources is the maximum number of resources that can = be accessible to a single shader stage in a pipeline layout. Descriptors with a type of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. For the fragment shader stage the framebuffer color attachments also count against this limit.

  • maxDescriptorSetSamplers is the maximum number of samplers tha= t can be included in descriptor bindings in= a pipeline layout across all pipeline shader stages and descriptor set numbers. Descriptors with a type of VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. See Sampler and Combined Image Sampler.

  • maxDescriptorSetUniformBuffers is the maximum number of unifor= m buffers that can be included in descripto= r bindings in a pipeline layout across all pipeline shader stages and descriptor set numbers. Descriptors with a type of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER o= r VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. See Uniform Buffer and Dynamic Uniform Buffer.

  • maxDescriptorSetUniformBuffersDynamic is the maximum number of dynamic uniform buffers that can be inclu= ded in descriptor bindings in a pipeline layout across all pipeline shader stages and descriptor set numbers. Descriptors with a type of VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. See Dynamic Uniform Buffer.

  • maxDescriptorSetStorageBuffers is the maximum number of storag= e buffers that can be included in descripto= r bindings in a pipeline layout across all pipeline shader stages and descriptor set numbers. Descriptors with a type of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER o= r VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. See Storage Buffer and Dynamic Storage Buffer.

  • maxDescriptorSetStorageBuffersDynamic is the maximum number of dynamic storage buffers that can be inclu= ded in descriptor bindings in a pipeline layout across all pipeline shader stages and descriptor set numbers. Descriptors with a type of VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. See Dynamic Storage Buffer.

  • maxDescriptorSetSampledImages is the maximum number of sampled images that can be included in descriptor= bindings in a pipeline layout across all pipeline shader stages and descriptor set numbers. Descriptors with a type of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, or VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER count against this lim= it. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. See Combined Image Sampler, Sampled Image, and Uniform Texel Buffer.

  • maxDescriptorSetStorageImages is the maximum number of storage images that can be included in descriptor= bindings in a pipeline layout across all pipeline shader stages and descriptor set numbers. Descriptors with a type of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, o= r VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER count against this lim= it. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. See Storage Image, and Storage Texel Buffer.

  • maxDescriptorSetInputAttachments is the maximum number of inpu= t attachments that can be included in descr= iptor bindings in a pipeline layout across all pipeline shader stages and descriptor set numbers. Descriptors with a type of VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT count against this limit. Only descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set count against this limit. See Input Attachment.

  • maxVertexInputAttributes is the maximum number of vertex input attributes that can be specified for a gr= aphics pipeline. These are described in the array of VkVertexInputAttributeDescription structures that are provided= at graphics pipeline creation time via the pVertexAttributeDescriptions member of the VkPipelineVertexInputStateCreateInfo structure. See Vertex Attributes and Vertex Input= Description.

  • maxVertexInp= utBindings is the maximum number of vertex buffers that can be specified for providing vertex attributes to a graphics pipeline. These are described in the array of VkVertexInputBindingDescription structures that are provided a= t graphics pipeline creation time via the pVertexBindingDescriptions member of the VkPipelineVertexInputStateCreateInfo structure. The binding member of VkVertexInputBindingDescription must be less than this limit. See Vertex Input Description.

  • maxVertexInputAttributeOffset is the maximum vertex input attribute offset that can be added to the= vertex input binding stride. The offset member of the VkVertexInputAttributeDescripti= on structure must be less than or equal to t= his limit. See Vertex Input Description.

  • maxVertexInputBindingStride is the maximum vertex input bindin= g stride that can be specified in a vertex = input binding. The stride member of the VkVertexInputBindingDescription= structure must be less than or equal to t= his limit. See Vertex Input Description.

  • maxVertexOutputComponents is the maximum number of components = of output variables which can be output by a= vertex shader. See Vertex Shaders.

  • maxTessellationGenerationLevel is the maximum tessellation generation level supported by the fixed-function tessellation primitive generator. See Tessellation.

  • maxTessellationPatchSize is the maximum patch size, in vertice= s, of patches that can be processed by the t= essellation control shader and tessellation primitive generator. The patchControlPoints member of the VkPipelineTessellationStateCreateInfo structure specified at pipeline creation time and the value provided in the OutputVertices execution mode of shader modules must be = less than or equal to this limit. See Tessellation.

  • maxTessellationControlPerVertexInputComponents is the maximum number of components of input variables which can<= /strong> be provided as per-vertex inputs to the tessellation control shader stage.

  • maxTessellationControlPerVertexOutputComponents is the maximum number of components of per-vertex output variables which can be output from the tessellation control shader stage.

  • maxTessellationControlPerPatchOutputComponents is the maximum number of components of per-patch output variables which can be output from the tessellation control shader stage.

  • maxTessellationControlTotalOutputComponents is the maximum tot= al number of components of per-vertex and per-patch output variables which can be output from the tessellation contr= ol shader stage.

  • maxTessellationEvaluationInputComponents is the maximum number= of components of input variables which can b= e provided as per-vertex inputs to the tessellation evaluation shader stage.

  • maxTessellationEvaluationOutputComponents is the maximum numbe= r of components of per-vertex output variables which ca= n be output from the tessellation evaluation shader stage.

  • maxGeometryShaderInvocations is the maximum invocation count supported for instanced geometry shaders. The value provided in the Invocations execution mode of shader modules must be less than or equal to thi= s limit. See Geometry Shading.

  • maxGeometryInputComponents is the maximum number of components= of input variables which can be provided as = inputs to the geometry shader stage.

  • maxGeometryOutputComponents is the maximum number of component= s of output variables which can be output from= the geometry shader stage.

  • maxGeometryOutputVertices is the maximum number of vertices wh= ich can be emitted by any geometry shader.

  • maxGeometryTotalOutputComponents is the maximum total number o= f components of output, across all emitted vertices, which can be output from the geometry shader stage.

  • maxFragmentInputComponents is the maximum number of components= of input variables which can be provided as = inputs to the fragment shader stage.

  • maxFragmentOutputAttachments is the maximum number of output attachments which can be written to by th= e fragment shader stage.

  • maxFragmentDualSrcAttachments is the maximum number of output attachments which can be written to by th= e fragment shader stage when blending is enabled and one of the dual source blend modes is in use. See Dual-Source Blending and dualSrcBlend.

  • maxFragmentCombinedOutputResources is the total number of stor= age buffers, storage images, and output buffers which = can be used in the fragment shader stage.

  • maxComputeSharedMemorySize is the maximum total storage size, = in bytes, of all variables declared with the WorkgroupLocal stora= ge class in shader modules (or with the shared storage qualifier = in GLSL) in the compute shader stage.

  • maxComputeWorkGroupCount[3] is the maximum number of local workgroups that can be dispatched by a si= ngle dispatch command. These three values represent the maximum number of local workgroups for the X, Y, and Z dimensions, respectively. The workgroup count parameters to the dispatch commands must be less than or equal to the corresponding limit. See Dispatching Commands.

  • maxComputeWorkGroupInvocations is the maximum total number of compute shader invocations in a single local workgroup. The product of the X, Y, and Z sizes as specified by the LocalSize execution mode in shader modules and by the object decorated by the WorkgroupSize decoration must be less than or equal to this limit.

  • maxComputeWorkGroupSize[3] is the maximum size of a local comp= ute workgroup, per dimension. These three values represent the maximum local workgroup size in the X, Y, and Z dimensions, respectively. The x, y, and z sizes specified by t= he LocalSize execution mode and by the object decorated by the WorkgroupSize decoration in shader modules must be less= than or equal to the corresponding limit.

  • subPixelPreci= sionBits is the number of bits of subpixel precision in framebuffer coordinates xf and yf. See Rasterization.

  • subTexelPreci= sionBits is the number of bits of precision in the division along an axis of an image used for minification and magnification filters. 2subTexelPrecisionBits is= the actual number of divisions along each axis of the image represented. Sub-texel values calculated during image sampling will snap to these locations when generating the filtered results.

  • mipmapPrecision= Bits is the number of bits of division that the LOD calculation for mipmap fetching get snapped to when determining the contribution from each mip level to the mip filtered results. 2mipmapPrecisionBits is t= he actual number of divisions.

    Note

    For example, if this value is 2 bits then when linearly filtering betwee= n two levels, each level could: contribute: 0%, 33%, 66%, or 100% (this is just an example and the amount of contribution sho= uld be covered by different equations in the spec).

  • maxDrawIndexedIndexValue is the maximum index value that can be used for indexed draw calls when using 32-bit indices. This excludes the primitive restart index value of 0xFFFFFFFF. See fullDrawIndexUint32.

  • maxDrawIndirec= tCount is the maximum draw count that is supported for indirect draw calls. See multiDrawIndirect.

  • maxSamplerLodBias= is the maximum absolute sampler LOD bias. The sum of the mipLodBias member of the VkSamplerCreateI= nfo structure and the Bias operand of image sampling operations in shader modules (or 0 if no Bias operand is provided to an imag= e sampling operation) are clamped to the range [-maxSamplerLodBias,+maxSamplerLodBia= s]. See [samplers-mipLodBias].

  • maxSamplerAnis= otropy is the maximum degree of sampler anisotropy. The maximum degree of anisotropic filtering used for an image sampling operation is the minimum of the maxAnisotropy member of the VkSamplerCreateInfo structure and this limit. See [samplers-maxAnisotropy].

  • maxViewports is= the maximum number of active viewports. The viewportCount member of the VkPipelineViewportStateCreateInfo structure that is provided a= t pipeline creation must be less than or eq= ual to this limit.

  • maxViewportDi= mensions[2] are the maximum viewport dimensions in the X (width) and Y (height) dimensions, respectively. The maximum viewport dimensions must be g= reater than or equal to the largest image which can be created and us= ed as a framebuffer attachment. See Controlling the Viewport.

  • viewportBoundsR= ange[2] is the [minimum, maximum] range that the corners of = a viewport must be contained in. This range must be at least [-2 =C3=97 size, 2 =C3=97 size - 1], where size = =3D max(maxViewportDimensions[0], maxViewportDimensions[1]). See Controlling the Viewport.

    Note

    The intent of the viewportBoundsRange limit is to allow a m= aximum sized viewport to be arbitrarily shifted relative to the output target as long as at least some portion intersects. This would give a bounds limit of [-size + = 1, 2 =C3=97 size - 1] which would allow all possible non-empty-set = intersections of the output target and the viewport. Since these numbers are typically powers of two, picking the signed number range using the smallest possible number of bits ends up with the specified range.

  • viewportSubPix= elBits is the number of bits of subpixel precision for viewport bounds. The subpixel precision that floating-point viewport bounds are interpreted at is given by this limit.

  • minMemoryMapA= lignment is the minimum required alignment, in bytes,= of host visible memory allocations within the host address space. When mapping a memory allocation with vkMapMemory, subtrac= ting offset bytes from the returned pointer will always produce an integer multiple of this limit. See Host Access to Device Memory Objects.

  • minTexelBufferOffsetAlignment is the minimum required alignment, in bytes, for the offset member of the VkBufferViewCreateInfo structure for texel buffers. When a buffer view is created for a buffer which was created with VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set in the usag= e member of the VkBufferCreateInfo structure, the offset must be an integer multiple of this limit.

  • minUniformBufferOffsetAlignment is the minimum required alignment, in bytes, for the offset member of the VkDescriptorBufferInfo structure for uniform buffers. When a descriptor of type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC is updated, the offset must be an integer mu= ltiple of this limit. Similarly, dynamic offsets for uniform buffers mus= t be multiples of this limit.

  • minStorageBufferOffsetAlignment is the minimum required alignment, in bytes, for the offset member of the VkDescriptorBufferInfo structure for storage buffers. When a descriptor of type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC is updated, the offset must be an integer mu= ltiple of this limit. Similarly, dynamic offsets for storage buffers mus= t be multiples of this limit.

  • minTexelOffset is the minimum offset value for the ConstOffset image operand of any of the OpImageSample* or OpImageFetch* image instruction= s.

  • maxTexelOffset is the maximum offset value for the ConstOffset image operand of any of the OpImageSample* or OpImageFetch* image instruction= s.

  • minTexelGather= Offset is the minimum offset value for the Offset or ConstOffsets<= /code> image operands of any of the OpImage*Gather image instr= uctions.

  • maxTexelGather= Offset is the maximum offset value for the Offset or ConstOffsets<= /code> image operands of any of the OpImage*Gather image instr= uctions.

  • minInterpola= tionOffset is the minimum negative offset value for the offset operand of= the InterpolateAtOffset extended instruction.

  • maxInterpola= tionOffset is the maximum positive offset value for the offset operand of= the InterpolateAtOffset extended instruction.

  • subPixelInterpolationOffsetBits is the number of subpixel fractional bits that the x and y offsets to the InterpolateAtOffset extended instruction may be rounded to as fixed-point values.

  • maxFramebufferW= idth is the maximum width for a framebuffer. The width member of the VkFramebufferCreateInfo s= tructure must be less than or equal to this limit.=

  • maxFramebuffer= Height is the maximum height for a framebuffer. The height member of the VkFramebufferCreateInfo = structure must be less than or equal to this limit.=

  • maxFramebuffer= Layers is the maximum layer count for a layered framebuffer. The layers member of the VkFramebufferCreateInfo = structure must be less than or equal to this limit.=

  • framebufferColorSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the color sampl= e counts that are supported for all framebuffer color attachments with floating- or fixed-point formats. There is no limit that specifies the color sample counts that are supported for all color attachments with integer formats.

  • framebufferDepthSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the supported d= epth sample counts for all framebuffer depth/stencil attachments, when the format includes a depth component.

  • framebufferStencilSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the supported s= tencil sample counts for all framebuffer depth/stencil attachments, when the format includes a stencil component.

  • framebufferNoAttachmentsSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the supported s= ample counts for a framebuffer with no attachments.

  • maxColorAttachm= ents is the maximum number of color attachments that can be used by a subpass in a render pass. The colorAttachmentCount member of the VkSubpassDescript= ion structure must be less than or equal to t= his limit.

  • sampledImageColorSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the sample coun= ts supported for all 2D images created with VK_IMAGE_TILING_OPTIMAL, usag= e containing VK_IMAGE_USAGE_SAMPLED_BIT, and a non-integer color format.

  • sampledImageIntegerSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the sample coun= ts supported for all 2D images created with VK_IMAGE_TILING_OPTIMAL, usag= e containing VK_IMAGE_USAGE_SAMPLED_BIT, and an integer color format.

  • sampledImageDepthSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the sample coun= ts supported for all 2D images created with VK_IMAGE_TILING_OPTIMAL, usag= e containing VK_IMAGE_USAGE_SAMPLED_BIT, and a depth format.

  • sampledImageStencilSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the sample supp= orted for all 2D images created with VK_IMAGE_TILING_OPTIMAL, usage containing VK_IMAGE_USAGE_SAMPLED_BIT, and a stencil format.

  • storageImageSampleCounts is a bitmask1 of VkSampleCountFlagBits indicating the sample coun= ts supported for all 2D images created with VK_IMAGE_TILING_OPTIMAL, and usage containing VK_IMAGE_USAGE_STORAGE_BIT.

  • maxSampleMaskWor= ds is the maximum number of array elements of a variable decorated with the SampleMask built-in decoration.

  • timestampComputeAndGraphics specifies support for timestamps o= n all graphics and compute queues. If this limit is set to VK_TRUE, all queues that advertise the VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT in = the VkQueueFamilyProperties::queueFlags support VkQueueFamilyProperties::timestampValidBits of at= least 36. See Timestamp Queries.

  • timestampPeriod is the number of nanoseconds required for a timestamp q= uery to be incremented by 1. See Timestamp Queries.

  • maxClipDistances is the maximum number of clip distances that can= be used in a single shader stage. The size of any array declared with the ClipDistance built-in decoration in a shader module must be les= s than or equal to this limit.

  • maxCullDistances is the maximum number of cull distances that can= be used in a single shader stage. The size of any array declared with the CullDistance built-in decoration in a shader module must be les= s than or equal to this limit.

  • maxCombinedClipAndCullDistances is the maximum combined number= of clip and cull distances that can be used = in a single shader stage. The sum of the sizes of any pair of arrays declared with the ClipDistance and CullDistance built-in decoration= used by a single shader stage in a shader module must be less than or equal to this limit.

  • discreteQueuePriorities is the number of discrete priorities t= hat can be assigned to a queue based on the v= alue of each member of VkDeviceQueueCreateInfo::pQueuePriorities. This must be at least 2, and levels must be spread evenly over the range, with at least one level at 1.0, and another at 0.0. See Queue Priority.

  • pointSizeRange[2] is the range [minimum,maximum] of su= pported sizes for points. Values written to variables decorated with the PointSize built= -in decoration are clamped to this range.

  • lineWidthRange[2] is the range [minimum,maximum] of su= pported widths for lines. Values specified by the lineWidth member of the VkPipelineRasterizationStateCreateInfo or the lineWidth<= /code> parameter to vkCmdSetLineWidth are clamped to this range.

  • pointSizeGranu= larity is the granularity of supported point sizes. Not all point sizes in the range defined by pointSizeRange are supported. This limit specifies the granularity (or increment) between successive supported point sizes.

  • lineWidthGranu= larity is the granularity of supported line widths. Not all line widths in the range defined by lineWidthRange are supported. This limit specifies the granularity (or increment) between successive supported line widths.

  • strictLines spec= ifies whether lines are rasterized according to the preferred method of rasterization. If set to VK_FALSE, lines may be rasterized under a relaxed set of rules. If set to VK_TRUE, lines are rasterized as per the strict definition. See Basic Line Segment Rasterization.

  • standardSampleLocations specifies whether rasterization uses t= he standard sample locations as documented in Multisampling. If set to VK_TRUE, the implementation uses the documented samp= le locations. If set to VK_FALSE, the implementation may use different sample locations.

  • optimalBufferCopyOffsetAlignment is the optimal buffer offset alignment in bytes for vkCmdCopyBufferToImage and vkCmdCopyImageToBuffer. The per texel alignment requirements are enforced, but applications should use the optimal alignment for opti= mal performance and power use.

  • optimalBufferCopyRowPitchAlignment is the optimal buffer row p= itch alignment in bytes for vkCmdCopyBufferToImage and vkCmdCopyImageToBuffer. Row pitch is the number of bytes between texels with the same X coordinate in adjacent rows (Y coordinates differ by one). The per texel alignment requirements are enforced, but applications should use the optimal alignment for opti= mal performance and power use.

  • nonCoherentAtom= Size is the size and alignment in bytes that bounds concurrent access to host-mapped device memory.

  • VkPhysicalDeviceDiscardRecta= nglePropertiesEXT::maxDiscardRectangles is the maximum number of active discard rectangles. This limit can be queried by setting the pNext pointer from a VkPhysicalDeviceProperties2 object to an i= nstance of VkPhysicalDeviceDiscardRecta= nglePropertiesEXT and using vkGetPhysicalDeviceProperties2 to fill out the members.

  • VkPhysicalDevicePointClippingPrope= rties::pointClippingBehavior defines the clipping behavior of points. This limit can be queried by setting the pNext pointer from a VkPhysicalDeviceProperties2 object to an i= nstance of VkPhysicalDevicePointClippingPrope= rties and using vkGetPhysicalDeviceProperties2 to fill out the members.

  • VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT::max= VertexAttribDivisor is the maximum value of the number of instances that will repeat the value of vertex attribute data when instanced rendering is enabled. This limit can be queried by setting the pNext pointer from a VkPhysicalDeviceProperties2 object to an i= nstance of VkPhysicalDeviceVertex= AttributeDivisorPropertiesEXT and using vkGetPhysicalDeviceProperties2 to fill out the members.

1

For all bitmasks of VkSampleCountFlagBits, th= e sample count limits defined above represent the minimum supported sample counts for each image type. Individual images may support additional = sample counts, which are queried using vkGetPhysicalDevice= ImageFormatProperties as described in Supported Sample Counts.

Bits which may be set in the sample co= unt limits returned by VkPhysicalDeviceLimits, as well as in other que= ries and structures representing image sample counts, are:

typedef enum VkSampleCountFlagB=
its {
    VK_SAMPLE_COUNT_1_BIT =3D 0x00000001,
    VK_SAMPLE_COUNT_2_BIT =3D 0x00000002,
    VK_SAMPLE_COUNT_4_BIT =3D 0x00000004,
    VK_SAMPLE_COUNT_8_BIT =3D 0x00000008,
    VK_SAMPLE_COUNT_16_BIT =3D 0x00000010,
    VK_SAMPLE_COUNT_32_BIT =3D 0x00000020,
    VK_SAMPLE_COUNT_64_BIT =3D 0x00000040,
} VkSampleCountFlagBits;
  • VK_SAMPLE_COUNT_1_BIT specifies an image with one sample pe= r pixel.

  • VK_SAMPLE_COUNT_2_BIT specifies an image with 2 samples per= pixel.

  • VK_SAMPLE_COUNT_4_BIT specifies an image with 4 samples per= pixel.

  • VK_SAMPLE_COUNT_8_BIT specifies an image with 8 samples per= pixel.

  • VK_SAMPLE_COUNT_16_BIT specifies an image with 16 samples p= er pixel.

  • VK_SAMPLE_COUNT_32_BIT specifies an image with 32 samples p= er pixel.

  • VK_SAMPLE_COUNT_64_BIT specifies an image with 64 samples p= er pixel.

typedef VkFlags VkSampleCountFlags;

VkSampleCountFlags is a bitmask type for setting a mask of = zero or more VkSampleCountFlagBits.

The VkPhysicalDevicePushDescriptorPropertiesKHR structure i= s defined as:

typedef struct VkPhysicalDevice=
PushDescriptorPropertiesKHR {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           maxPushDescriptors;
} VkPhysicalDevicePushDescriptorPropertiesKHR;

The members of the VkPhysicalDevicePushDescriptorPropertiesKHR structure describe the following implementation-dependent limits:

  • maxPushDescripto= rs is the maximum number of descriptors that can be= used in a descriptor set created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR set.

The VkPhysicalDeviceMultiviewProperties structure is define= d as:

typedef struct VkPhysicalDevice=
MultiviewProperties {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           maxMultiviewViewCount;
    uint32_t           maxMultiviewInstanceIndex;
} VkPhysicalDeviceMultiviewProperties;

or the equivalent

typedef VkPhysicalDeviceMultiviewProperties VkPhysicalDeviceMu=
ltiviewPropertiesKHR;

The members of the VkPhysicalDeviceMultiviewProperties stru= cture describe the following implementation-dependent limits:

  • maxMultiviewV= iewCount is one greater than the maximum view index that can be used in a subpass.

  • maxMultiviewInstanceIndex is the maximum valid value of instan= ce index allowed to be generated by a drawing command recorded within a subpass of a multiview render pass instance.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES

If the VkPhysicalDeviceMultiviewProperties structure is inc= luded in the pNext chain of VkPhysicalDevi= ceProperties2, it is filled with the implementation-dependent limits.

The VkPhysicalDeviceDiscardRectanglePropertiesEXT structure= is defined as:

typedef struct VkPhysicalDevice=
DiscardRectanglePropertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           maxDiscardRectangles;
} VkPhysicalDeviceDiscardRectanglePropertiesEXT;

The members of the VkPhysicalDeviceDiscardRectanglePropertiesEXT structure describe the following implementation-dependent limits:

  • maxDiscardRectangles is the maximum number of discard recta= ngles that can be specified.

Valid Usage (Implicit)
  • sType must be VK= _STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT

If the VkPhysicalDeviceDiscardRectanglePropertiesEXT struct= ure is included in the pNext chain of Vk= PhysicalDeviceProperties2, it is filled with the implementation-dependent limits.

The VkPhysicalDeviceSampleLocationsPropertiesEXT structure = is defined as:

typedef struct VkPhysicalDevice=
SampleLocationsPropertiesEXT {
    VkStructureType       sType;
    void*                 pNext;
    VkSampleCountFlags    sampleLocationSampleCounts;
    VkExtent2D            maxSampleLocationGridSize;
    float                 sampleLoca=
tionCoordinateRange[2];
    uint32_t              sampleLocationSubPixelBits;
    VkBool32              variableSampleLocations;
} VkPhysicalDeviceSampleLocationsPropertiesEXT;

The members of the VkPhysicalDeviceSampleLocationsPropertiesEXT structure describe the following implementation-dependent limits:

  • sampleLocationSampleCounts is a bitmask of VkSampleCountFlagBits indicating the sample coun= ts supporting custom sample locations.

  • maxSampleLocationGridSize is the maximum size of the pixel gri= d in which sample locations can vary that is s= upported for all sample counts in sampleLocationSampleCounts.

  • sampleLocationCoordinateRange[2] is the range of supported sam= ple location coordinates.

  • sampleLocationSubPixelBits is the number of bits of subpixel precision for sample locations.

  • variableSampleLocations specifies whether the sample locations used by all pipelines that will be bound to a command buffer during a subpass must match. If set to VK_TRUE, the implementation supports variable sample locations in a subpass. If set to VK_FALSE, then the sample locations must stay constant in each subpass.

Valid Usage (Implicit)
  • = sType must be VK_= STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT

If the VkPhysicalDeviceSampleLocationsPropertiesEXT structu= re is included in the pNext chain of Vk= PhysicalDeviceProperties2, it is filled with the implementation-dependent limits.

The VkPhysicalDeviceExternalMemoryHostPropertiesEXT structu= re is defined as:

typedef struct VkPhysicalDevice=
ExternalMemoryHostPropertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    VkDeviceSize       minImportedHostPointerAlignment;
} VkPhysicalDeviceExternalMemoryHostPropertiesEXT;

The members of the VkPhysicalDeviceExternalMemoryHostPropertiesEXT= structure describe the following implementation-dependent limits:

  • minImportedHostPointerAlignment is the minimum required alignment, in bytes, for the base address and size of host pointers that can be imported to a Vulkan memory object= .

Valid Usage (Implicit)
  • sType must be = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT

If the VkPhysicalDeviceExternalMemoryHostPropertiesEXT stru= cture is included in the pNext chain of VkPhysicalDeviceProperties2KHR, it is filled with the implementation-dependent limits.

The VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX= structure is defined as:

typedef struct VkPhysicalDevice=
MultiviewPerViewAttributesPropertiesNVX {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           perViewPositionAllComponents;
} VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX;

The members of the VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX struct= ure describe the following implementation-dependent limits:

  • perViewPositionAllComponents is VK_TRUE if the implementation supports per-view position values that differ in components other than the X component.

Valid Usage (Implicit)
  • sType must b= e VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PRO= PERTIES_NVX

If the VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX structure is included in the pNext chain of VkPhysicalDeviceProperties2, it is filled = with the implementation-dependent limits.

The VkPhysicalDevicePointClippingProperties structure is de= fined as:

typedef struct VkPhysicalDevice=
PointClippingProperties {
    VkStructureType            sType;
    void*                      pNext;
    VkPointClippingBehavior    pointClippingBehavior;
} VkPhysicalDevicePointClippingProperties;

or the equivalent

typedef VkPhysicalDevicePointClippingProperties VkPhysicalDevi=
cePointClippingPropertiesKHR;

The members of the VkPhysicalDevicePointClippingProperties = structure describe the following implementation-dependent limit:

  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • pointClippingBehavior is the point clipping behavior suppor= ted by the implementation, and is of type VkPointClipping= Behavior.

If the VkPhysicalDevicePointClippingProperties structure is= included in the pNext chain of VkPhysicalD= eviceProperties2, it is filled with the implementation-dependent limits.

Valid Usage (Implicit)
  • = sType must be VK_STRUC= TURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES

The VkPhysicalDeviceSubgroupProperties structure is defined= as:

typedef struct VkPhysicalDevice=
SubgroupProperties {
    VkStructureType           sType;
    void*                     pNext;
    uint32_t                  subgroupSize;
    VkShaderStageFlags        supportedStages;
    VkSubgroupFeatureFlags    supportedOperations;
    VkBool32                  quadOperationsInAllStages;
} VkPhysicalDeviceSubgroupProperties;

The members of the VkPhysicalDeviceSubgroupProperties struc= ture describe the following implementation-dependent limits:

  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • subgroupSize is the number of invocations in each subgroup. This will match any SubgroupSize decorated variable used in any shader module created on this device. subgroupSize is at least 1 if any of the physical device=E2=80= =99s queues support VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT.

  • supportedStages is a bitfield of VkS= haderStageFlagBits describing the shader stages that subgroup operations are supported in. supportedStages will have the VK_SHADER_STAGE_COMPUTE_BI= T bit set if any of any of the physical device=E2=80=99s queues support VK_QUEUE_COMPUTE_BIT.

  • supportedOperations is a bitmask of VkSubgroupFeatureFlagBits specifying the set= s of subgroup operations supported on this device. supportedOperations will have the VK_SUBGROUP_FEATURE_BASIC_BIT bit set if any of the physical device=E2=80=99s queues support VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT.

  • quadOperationsInAllStages is a boolean that specifies wheth= er quad subgroup operations are available in all stages, or are restricted to fragment and compute stages.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_= TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES

If the VkPhysicalDeviceSubgroupProperties structure is incl= uded in the pNext chain of VkPhysicalDevicePr= operties2, it is filled with the implementation-dependent limits.

Bits which can be set in VkPhysicalDeviceSubgroupProperties:= :supportedOperations to specify supported subgroup operations are:

typedef enum VkSubgroupFeatureF=
lagBits {
    VK_SUBGROUP_FEATURE_BASIC_BIT =3D 0x00000001=
,
    VK_SUBGROUP_FEATURE_VOTE_BIT =3D 0x00000002,
    VK_SUBGROUP_FEATURE_ARITHMETIC_BIT =3D 0x00000004,
    VK_SUBGROUP_FEATURE_BALLOT_BIT =3D 0x00000008,
    VK_SUBGROUP_FEATURE_SHUFFLE_BIT =3D 0x00000010,
    VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT =3D 0x0000=
0020,
    VK_SUBGROUP_FEATURE_CLUSTERED_BIT =3D 0x00000040,
    VK_SUBGROUP_FEATURE_QUAD_BIT =3D 0x00000080,
    VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV =3D 0x000001=
00,
} VkSubgroupFeatureFlagBits;
  • VK_SUBGROUP_FEATUR= E_BASIC_BIT specifies the device will accept SPIR-V shader modules that contain the GroupNonUniform capability.

  • VK_SUBGROUP_FEATURE= _VOTE_BIT specifies the device will accept SPIR-V shader modules that contain the GroupNonUniformVote capability.

  • VK_SUBGROUP_FEATURE_ARITHMETIC_BIT specifies the device will accept SPIR-V shader modules that contain the GroupNonUniformArithmetic capability.

  • VK_SUBGROUP_FEATURE_BALLOT_BIT specifies the device will accep= t SPIR-V shader modules that contain the GroupNonUniformBallot capability.

  • VK_SUBGROUP_FEATURE_SHUFFLE_BIT specifies the device will acce= pt SPIR-V shader modules that contain the GroupNonUniformShuffle capability.

  • VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT specifies the device = will accept SPIR-V shader modules that contain the GroupNonUniformShuffleRelative capability.

  • VK_SUBGROUP_FEATURE_CLUSTERED_BIT specifies the device will ac= cept SPIR-V shader modules that contain the GroupNonUniformClustered capability.

  • VK_SUBGROUP_FEATURE= _QUAD_BIT specifies the device will accept SPIR-V shader modules that contain the GroupNonUniformQuad capability.

  • VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV specifies the device wi= ll accept SPIR-V shader modules that contain the GroupNonUniformPartitionedNV capability.

typedef VkFlags VkSubgroupFeatureFlags;

VkSubgroupFeatureFlags is a bitmask type for setting a mask= of zero or more VkSubgroupFeatureFlagBits.

The VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT str= ucture is defined as:

typedef struct VkPhysicalDevice=
BlendOperationAdvancedPropertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           advancedBlendMaxColorAttachments;
    VkBool32           advancedBlendIndependentBlend;
    VkBool32           advancedBlendNonPremultipliedSrcColor;
    VkBool32           advancedBlendNonPremultipliedDstColor;
    VkBool32           advancedBlendCorrelatedOverlap;
    VkBool32           advancedBlendAllOperations;
} VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT;

The members of the VkPhysicalDeviceBlendOperationAdvancedPropertie= sEXT structure describe the following implementation-dependent limits:

  • advancedBlendMaxColorAttachments is one greater than the highe= st color attachment index that can be used i= n a subpass, for a pipeline that uses an advanced blend operation.

  • advancedBlendIndependentBlend specifies whether advanced blend operations can vary per-attachment.

  • advancedBlendNonPremultipliedSrcColor specifies whether the so= urce color can be treated as non-premultiplied= . If this is VK_FALSE, then VkPipelineColorBlendAdvance= dStateCreateInfoEXT::srcPremultiplied must be VK_TRUE.

  • advancedBlendNonPremultipliedDstColor specifies whether the destination color can be treated as non-p= remultiplied. If this is VK_FALSE, then VkPipelineColorBlendAdvance= dStateCreateInfoEXT::dstPremultiplied must be VK_TRUE.

  • advancedBlendCorrelatedOverlap specifies whether the overlap m= ode can be treated as correlated. If this is VK_FALSE, then VkPipelineColorBlendAdvance= dStateCreateInfoEXT::blendOverlap must be VK_BLEND_OVERLAP_UNCORRELAT= ED_EXT.

  • advancedBlendAllOperations specifies whether all advanced blen= d operation enums are supported. See the valid usage of VkPipelineColor= BlendAttachmentState.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_E= XT

If the VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT = structure is included in the pNext chain of VkPhysicalDeviceProperties2, it is filled with the implementation-dependent limits.

The VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT str= ucture is defined as:

typedef struct VkPhysicalDevice=
VertexAttributeDivisorPropertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           maxVertexAttribDivisor;
} VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT;

The members of the VkPhysicalDeviceVertexAttributeDivisorPropertie= sEXT structure describe the following implementation-dependent limits:

  • maxVertexAtt= ribDivisor is the maximum value of the number of instances that will repeat the value of vertex attribute data when instanced rendering is enabled.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_E= XT

The VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT struct= ure is defined as:

typedef struct VkPhysicalDevice=
SamplerFilterMinmaxPropertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           filterMinmaxSingleComponentFormats;
    VkBool32           filterMinmaxImageComponentMapping;
} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT;

The members of the VkPhysicalDeviceSamplerFilterMinmaxPropertiesEX= T structure describe the following implementation-dependent limits:

  • filterMinmaxSingleComponentFormats is a boolean value indicati= ng whether a minimum set of required formats support min/max filtering.

  • filterMinmaxImageComponentMapping is a boolean value indicatin= g whether the implementation supports non-identity component mapping of the image when doing min/max filtering.

If the VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT str= ucture is included in the pNext chain of Vk= PhysicalDeviceProperties2, it is filled with the implementation-dependent limits.

If filterMinmaxSingleComponentFormats is VK_TRUE, the following formats must support the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT feature = with VK_IMAGE_TILING_OPTIMAL, if they support VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT.

  • VK_FORMAT_R8_UNORM

  • VK_FORMAT_R8_SNORM

  • VK_FORMAT_R16_UNORM

  • VK_FORMAT_R16_SNORM

  • VK_FORMAT_R16_SFLOAT

  • VK_FORMAT_R32_SFLOAT

  • VK_FORMAT_D16_UNORM

  • VK_FORMAT_X8_D24_UNORM_PACK32

  • VK_FORMAT_D32_SFLOAT

  • VK_FORMAT_D16_UNORM_S8_UINT

  • VK_FORMAT_D24_UNORM_S8_UINT

  • VK_FORMAT_D32_SFLOAT_S8_UINT

If the format is a depth/stencil format, this bit only specifies that th= e depth aspect (not the stencil aspect) of an image of this format supports min/max filtering, and that min/max filtering of the depth aspect is supported when depth compare is disabled in the sampler.

If filterMinmaxImageComponentMapping is VK_FALSE the component mapping of the image view used with min/max filtering must have been created with the r component set to VK_COMPONENT_SWIZZLE_IDENTITY. Only the r component of the sampled image value is defined and= the other component values are undefined. If filterMinmaxImageComponentMapping is VK_TRUE t= his restriction does not apply and image component mapping works as normal.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT

The VkPhysicalDeviceProtectedMemoryProperties structure is = defined as:

typedef struct VkPhysicalDevice=
ProtectedMemoryProperties {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           protectedNoFault;
} VkPhysicalDeviceProtectedMemoryProperties;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • protectedNoFault specifies whether the undefined behavior w= ill not include process termination or device loss. If protectedNoFault is VK_FALSE, undefined behavi= or may include process termination or device loss. If protectedNoFault is VK_TRUE, undefined behavio= r will not include process termination or device loss.

If the VkPhysicalDeviceProtectedMemoryProperties structure = is included in the pNext chain of VkPhysicalD= eviceProperties2, it is filled with a value indicating the implementation-dependent behavior.

The VkPhysicalDeviceMaintenance3Properties structure is def= ined as:

typedef struct VkPhysicalDevice=
Maintenance3Properties {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           maxPerSetDescriptors;
    VkDeviceSize       maxMemoryAllocationSize;
} VkPhysicalDeviceMaintenance3Properties;

or the equivalent

typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDevic=
eMaintenance3PropertiesKHR;

The members of the VkPhysicalDeviceMaintenance3Properties s= tructure describe the following implementation-dependent limits:

  • maxPerSetDescr= iptors is a maximum number of descriptors (summed over all descriptor types) in a single descriptor set that is guaranteed to satisfy any implementation-dependent constraints on the size of a descriptor set itself. Applications can query whether a descript= or set that goes beyond this limit is supported using vkGetDescriptorSe= tLayoutSupport.

  • maxMemoryAllocationSize is the maximum size of a memory alloca= tion that can be created, even if there is mor= e space available in the heap.

If the VkPhysicalDeviceMaintenance3Properties structure is = included in the pNext chain of VkPhysicalDevi= ceProperties2, it is filled with the implementation-dependent limits.

Valid Usage (Implicit)
  • <= code>sType must be VK_STRUCT= URE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES

The VkPhysicalDeviceDescriptorIndexingPropertiesEXT structu= re is defined as:

typedef struct VkPhysicalDevice=
DescriptorIndexingPropertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           maxUpdateAfterBindDescriptorsInAllPools;
    VkBool32           shaderUniformBufferArrayNonUniformIndexingNative;
    VkBool32           shaderSampledImageArrayNonUniformIndexingNative;
    VkBool32           shaderStorageBufferArrayNonUniformIndexingNative;
    VkBool32           shaderStorageImageArrayNonUniformIndexingNative;
    VkBool32           shaderInputAttachmentArrayNonUniformIndexingNative;
    VkBool32           robustBufferAccessUpdateAfterBind;
    VkBool32           quadDivergentImplicitLod;
    uint32_t           maxPerStageDescriptorUpdateAfterBindSamplers;
    uint32_t           maxPerStageDescriptorUpdateAfterBindUniformBuffers;
    uint32_t           maxPerStageDescriptorUpdateAfterBindStorageBuffers;
    uint32_t           maxPerStageDescriptorUpdateAfterBindSampledImages;
    uint32_t           maxPerStageDescriptorUpdateAfterBindStorageImages;
    uint32_t           maxPerStageDescriptorUpdateAfterBindInputAttachments=
;
    uint32_t           maxPerStageUpdateAfterBindResources;
    uint32_t           maxDescriptorSetUpdateAfterBindSamplers;
    uint32_t           maxDescriptorSetUpdateAfterBindUniformBuffers;
    uint32_t           maxDescriptorSetUpdateAfterBindUniformBuffersDynamic=
;
    uint32_t           maxDescriptorSetUpdateAfterBindStorageBuffers;
    uint32_t           maxDescriptorSetUpdateAfterBindStorageBuffersDynamic=
;
    uint32_t           maxDescriptorSetUpdateAfterBindSampledImages;
    uint32_t           maxDescriptorSetUpdateAfterBindStorageImages;
    uint32_t           maxDescriptorSetUpdateAfterBindInputAttachments;
} VkPhysicalDeviceDescriptorIndexingPropertiesEXT;

The members of the VkPhysicalDeviceDescriptorIndexingPropertiesEXT= structure describe the following implementation-dependent limits:

  • maxUpdateAfterBindDescriptorsInAllPools is the maximum number = of descriptors (summed over all descriptor types) that can be created across all pools that are created with the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT bit set. Pool creation may fail when this limit is= exceeded, or when the space this limit represents is unable to satisfy a pool creation due to fragmentation.

  • shaderUniformBufferArrayNonUniformIndexingNative is a boolean value indicating whether uniform buffer descriptors natively support nonuniform indexing. If this is VK_FALSE, then a single dynamic instance of an instruction that nonuniformly indexes an array of uniform buffers may execute multiple times in order to access all the descriptors.

  • shaderSampledImageArrayNonUniformIndexingNative is a boolean v= alue indicating whether sampler and image descriptors natively support nonuniform indexing. If this is VK_FALSE, then a single dynamic instance of an instruction that nonuniformly indexes an array of samplers or images may execute multiple times in order to ac= cess all the descriptors.

  • shaderStorageBufferArrayNonUniformIndexingNative is a boolean value indicating whether storage buffer descriptors natively support nonuniform indexing. If this is VK_FALSE, then a single dynamic instance of an instruction that nonuniformly indexes an array of storage buffers may execute multiple times in order to access all the descriptors.

  • shaderStorageImageArrayNonUniformIndexingNative is a boolean v= alue indicating whether storage image descriptors natively support nonuniform indexing. If this is VK_FALSE, then a single dynamic instance of an instruction that nonuniformly indexes an array of storage images may execute multiple times in order to access all the descriptors.

  • shaderInputAttachmentArrayNonUniformIndexingNative is a boolea= n value indicating whether input attachment descriptors natively support nonuniform indexing. If this is VK_FALSE, then a single dynamic instance of an instruction that nonuniformly indexes an array of input attachments may execute multiple times in order to access all the descriptors.

  • robustBufferAccessUpdateAfterBind is a boolean value indicatin= g whether robustBufferAccess can be enabled in a device simulta= neously with descriptorBindingUniformBufferUpdateAfterBind, descriptorBindingStorageBufferUpdateAfterBind, descriptorBindingUniformTexelBufferUpdateAfterBind, and/or descriptorBindingStorageTexelBufferUpdateAfterBind. If this is VK_FALSE, then either robustBufferAccess must be disabled or all of these update-after-bind features must be disabled.

  • quadDivergentImplicitLod is a boolean value indicating whether implicit level of detail calculations for image operations have well-defined results when the image and/or sampler objects used for the instruction are not uniform within a quad. See Derivative Image Operations.

  • <= /a> maxPerStageDescriptorUpdateAfterBindSamplers is similar to maxPerStageDescriptorSamplers but counts descriptors from descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxPerStageDescriptorUpdateAfterBindUniformBuffers is similar = to maxPerStageDescriptorUniformBuffers but counts descriptors fro= m descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxPerStageDescriptorUpdateAfterBindStorageBuffers is similar = to maxPerStageDescriptorStorageBuffers but counts descriptors fro= m descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxPerStageDescriptorUpdateAfterBindSampledImages is similar t= o maxPerStageDescriptorSampledImages but counts descriptors from descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxPerStageDescriptorUpdateAfterBindStorageImages is similar t= o maxPerStageDescriptorStorageImages but counts descriptors from descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxPerStageDescriptorUpdateAfterBindInputAttachments is simila= r to maxPerStageDescriptorInputAttachments but counts descriptors f= rom descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxPerStageUpdateAfterBindResources is similar to maxPerStageResources but counts descriptors from descriptor se= ts created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxDescriptorSetUpdateAfterBindSamplers is similar to maxDescriptorSetSamplers but counts descriptors from descripto= r sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • = maxDescriptorSetUpdateAfterBindUniformBuffers is similar to maxDescriptorSetUniformBuffers but counts descriptors from descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxDescriptorSetUpdateAfterBindUniformBuffersDynamic is simila= r to maxDescriptorSetUniformBuffersDynamic but counts descriptors f= rom descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • = maxDescriptorSetUpdateAfterBindStorageBuffers is similar to maxDescriptorSetStorageBuffers but counts descriptors from descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxDescriptorSetUpdateAfterBindStorageBuffersDynamic is simila= r to maxDescriptorSetStorageBuffersDynamic but counts descriptors f= rom descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • <= /a> maxDescriptorSetUpdateAfterBindSampledImages is similar to maxDescriptorSetSampledImages but counts descriptors from descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • <= /a> maxDescriptorSetUpdateAfterBindStorageImages is similar to maxDescriptorSetStorageImages but counts descriptors from descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

  • maxDescriptorSetUpdateAfterBindInputAttachments is similar to maxDescriptorSetInputAttachments but counts descriptors from descriptor sets created with or without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT= bit set.

If the VkPhysicalDeviceDescriptorIndexingPropertiesEXT stru= cture is included in the pNext chain of VkPhysicalDeviceProperties2KHR, it is filled with the implementation-dependent limits.

Valid Usage (Implicit)
  • sType must be = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT=

The VkPhysicalDeviceConservativeRasterizationPropertiesEXT = structure is defined as:

typedef struct VkPhysicalDevice=
ConservativeRasterizationPropertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    float              primitiveOver=
estimationSize;
    float              maxExtraPrimi=
tiveOverestimationSize;
    float              extraPrimitiv=
eOverestimationSizeGranularity;
    VkBool32           primitiveUnderestimation;
    VkBool32           conservativePointAndLineRasterization;
    VkBool32           degenerateTrianglesRasterized;
    VkBool32           degenerateLinesRasterized;
    VkBool32           fullyCoveredFragmentShaderInputVariable;
    VkBool32           conservativeRasterizationPostDepthCoverage;
} VkPhysicalDeviceConservativeRasterizationPropertiesEXT;

The members of the VkPhysicalDeviceConservativeRasterizationPropertiesEXT structu= re describe the following implementation-dependent limits:

  • primitiveOverestimationSize is the size in pixels the generati= ng primitive is increased at each of its edges during conservative rasterization overestimation mode. Even with a size of 0.0, conservative rasterization overestimation rules still apply and if any part of the pixel rectangle is covered by the generating primitive, fragments are generated for the entire pixel. However implementations may make the pixe= l coverage area even more conservative by increasing the size of the generating primitive.

  • maxExtraPrimitiveOverestimationSize is the maximum size in pix= els of extra overestimation the implementation supports in the pipeline state. A value of 0.0 means the implementation does not support any additional overestimation of the generating primitive during conservative rasterization. A value above 0.0 allows the application to further increase the size of the generating primitive during conservative rasterization overestimation.

  • extraPrimitiveOverestimationSizeGranularity is the granularity= of extra overestimation that can be specified in the pipeline state between 0.0 and maxExtraPrimitiveOverestimationSize inclusive. A value of 0.0 means the implementation can use the smallest representable non-zero value in the screen space pixel fixed-point grid.

  • primitiveUnderestimation is true if the implementation support= s the VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT conservative rasterization mode in addition to VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT. Otherwise the implementation only supports VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT.

  • conservativePointAndLineRasterization is true if the implementation supports conservative rasterization of point and line primitives as well as triangle primitives. Otherwise the implementation only supports triangle primitives.

  • degenerateTrianglesRasterized is false if the implementation c= ulls primitives generated from triangles that become zero area after they are quantized to the fixed-point rasterization pixel grid. degenerateTrianglesRasterized is true if these primitives are = not culled and the provoking vertex attributes and depth value are used for the fragments. The primitive area calculation is done on the primitive generated from the clipped triangle if applicable. Zero area primitives are backfacing and the application can enable backface culling if desired.

  • degenerateLinesRasterized is false if the implementation culls lines that become zero length after they are quantized to the fixed-point rasterization pixel grid. degenerateLinesRasterized is true if zero length lines are not culled and the provoking vertex attributes and depth value are used for the fragments.

  • fullyCoveredFragmentShaderInputVariable is true if the implementation supports the SPIR-V builtin fragment shader input variable FullyCoveredEXT which specifies that conservative rasterization is enabled and the fragment pixel square is fully covered by the generating primitive.

  • conservativeRasterizationPostDepthCoverage is true if the implementation supports conservative rasterization with the PostDepthCoverage execution mode enabled. When supported the SampleMask built-in input variable will ref= lect the coverage after the early per-fragment depth and stencil tests are applied even when conservative rasterization is enabled. Otherwise PostDepthCoverage execution mode must not be used when cons= ervative rasterization is enabled.

Valid Usage (Implicit)
  • sType must be= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERT= IES_EXT

If the VkPhysicalDeviceConservativeRasterizationPropertiesEXT structure is included in the pNext chain of VkPhysicalDeviceProperties2KHR, it is f= illed with the implementation-dependent limits and properties.

The VkPhysicalDeviceShaderCorePropertiesAMD structure is de= fined as:

typedef struct VkPhysicalDevice=
ShaderCorePropertiesAMD {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           shaderEngineCount;
    uint32_t           shaderArraysPerEngineCount;
    uint32_t           computeUnitsPerShaderArray;
    uint32_t           simdPerComputeUnit;
    uint32_t           wavefrontsPerSimd;
    uint32_t           wavefrontSize;
    uint32_t           sgprsPerSimd;
    uint32_t           minSgprAllocation;
    uint32_t           maxSgprAllocation;
    uint32_t           sgprAllocationGranularity;
    uint32_t           vgprsPerSimd;
    uint32_t           minVgprAllocation;
    uint32_t           maxVgprAllocation;
    uint32_t           vgprAllocationGranularity;
} VkPhysicalDeviceShaderCorePropertiesAMD;

The members of the VkPhysicalDeviceShaderCorePropertiesAMD = structure describe the following implementation-dependent limits:

  • shaderEngineCount= is an unsigned integer value indicating the number of shader engines found inside the shader core of the physical device.

  • shaderArraysPerEngineCount is an unsigned integer value indica= ting the number of shader arrays inside a shader engine. Each shader array has its own scan converter, set of compute units, and a render back end (color and depth buffers). Shader arrays within a shader engine share shader processor input (wave launcher) and shader export (export buffer) units. Currently, a shader engine can have one or two shader arrays.

  • computeUnitsPerShaderArray is an unsigned integer value indica= ting the number of compute units within a shader array. A compute unit houses a set of SIMDs along with a sequencer module and a local data store.

  • simdPerComputeUn= it is an unsigned integer value indicating the number of SIMDs inside a compute unit. Each SIMD processes a single instruction at a time.

  • wavefrontSize = is an unsigned integer value indicating the number of channels (or threads) in a wavefront.

  • sgprsPerSimd is= an unsigned integer value indicating the number of physical Scalar General Purpose Registers (SGPRs) per SIMD.

  • minSgprAllocation= is an unsigned integer value indicating the minimum number of SGPRs allocated for a wave.

  • maxSgprAllocation= is an unsigned integer value indicating the maximum number of SGPRs allocated for a wave.

  • sgprAllocationGranularity is an unsigned integer value indicat= ing the granularity of SGPR allocation for a wave.

  • vgprsPerSimd is= an unsigned integer value indicating the number of physical Vector General Purpose Registers (VGPRs) per SIMD.

  • minVgprAllocation= is an unsigned integer value indicating the minimum number of VGPRs allocated for a wave.

  • maxVgprAllocation= is an unsigned integer value indicating the maximum number of VGPRs allocated for a wave.

  • vgprAllocationGranularity is an unsigned integer value indicat= ing the granularity of VGPR allocation for a wave.

Valid Usage (Implicit)
  • = sType must be VK_STRUC= TURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD

If the VkPhysicalDeviceShaderCorePropertiesAMD structure is= included in the pNext chain of VkPhysicalD= eviceProperties2, it is filled with the implementation-dependent limits.

32.2.1. Limit Requirements

The following table specifies the required minimum/maximum for all Vulkan graphics implementations. Where a limit corresponds to a fine-grained device feature which is optional, the feature name is listed with= two required limits, one when the feature is supported and one when it is not supported. If an implementation supports a feature, the limits reported are the same whether or not the feature is enabled.

Table 45. Required Limit Types
Type Limit Feature

uint32_t

maxImageDimension1D

-

uint32_t

maxImageDimension2D

-

uint32_t

maxImageDimension3D

-

uint32_t

maxImageDimensionCube

-

uint32_t

maxImageArrayLayers

-

uint32_t

maxTexelBufferElements

-

uint32_t

maxUniformBufferRange

-

uint32_t

maxStorageBufferRange

-

uint32_t

maxPushConstantsSize

-

uint32_t

maxMemoryAllocationCount

-

uint32_t

maxSamplerAllocationCount

-

VkDeviceSize

bufferImageGranularity

-

VkDeviceSize

sparseAddressSpaceSize

spa= rseBinding

uint32_t

maxBoundDescriptorSets

-

uint32_t

maxPerStageDescriptorSamplers

-

uint32_t

maxPerStageDescriptorUniformBuffers

-

uint32_t

maxPerStageDescriptorStorageBuffers

-

uint32_t

maxPerStageDescriptorSampledImages

-

uint32_t

maxPerStageDescriptorStorageImages

-

uint32_t

maxPerStageDescriptorInputAttachments

-

uint32_t

maxPerStageResources

-

uint32_t

maxDescriptorSetSamplers

-

uint32_t

maxDescriptorSetUniformBuffers

-

uint32_t

maxDescriptorSetUniformBuffersDynamic

-

uint32_t

maxDescriptorSetStorageBuffers

-

uint32_t

maxDescriptorSetStorageBuffersDynamic

-

uint32_t

maxDescriptorSetSampledImages

-

uint32_t

maxDescriptorSetStorageImages

-

uint32_t

maxDescriptorSetInputAttachments

-

uint32_t

maxVertexInputAttributes

-

uint32_t

maxVertexInputBindings

-

uint32_t

maxVertexInputAttributeOffset

-

uint32_t

maxVertexInputBindingStride

-

uint32_t

maxVertexOutputComponents

-

uint32_t

maxTessellationGenerationLevel

tessellationShader

uint32_t

maxTessellationPatchSize

tessellationShader

uint32_t

maxTessellationControlPerVertexInputComponents

tessellationShader

uint32_t

maxTessellationControlPerVertexOutputComponents

tessellationShader

uint32_t

maxTessellationControlPerPatchOutputComponents

tessellationShader

uint32_t

maxTessellationControlTotalOutputComponents

tessellationShader

uint32_t

maxTessellationEvaluationInputComponents

tessellationShader

uint32_t

maxTessellationEvaluationOutputComponents

tessellationShader

uint32_t

maxGeometryShaderInvocations

geometryShader

uint32_t

maxGeometryInputComponents

geometryShader

uint32_t

maxGeometryOutputComponents

geometryShader

uint32_t

maxGeometryOutputVertices

geometryShader

uint32_t

maxGeometryTotalOutputComponents

geometryShader

uint32_t

maxFragmentInputComponents

-

uint32_t

maxFragmentOutputAttachments

-

uint32_t

maxFragmentDualSrcAttachments

dualSrcBlend

uint32_t

maxFragmentCombinedOutputResources

-

uint32_t

maxComputeSharedMemorySize

-

3 = =C3=97 uint32_t

maxComputeWorkGroupCount

-

uint32_t

maxComputeWorkGroupInvocations

-

3 = =C3=97 uint32_t

maxComputeWorkGroupSize

-

uint32_t

subPixelPrecisionBits

-

uint32_t

subTexelPrecisionBits

-

uint32_t

mipmapPrecisionBits

-

uint32_t

maxDrawIndexedIndexValue

fullDrawIndexUint32

uint32_t

maxDrawIndirectCount

multiDrawIndirect

float

maxSamplerLodBias

-

float

maxSamplerAnisotropy

samplerAnisotropy

uint32_t

maxViewports

multiViewport

2 = =C3=97 uint32_t

maxViewportDimensions

-

2 = =C3=97 float

viewportBoundsRange

-

uint32_t

viewportSubPixelBits

-

size_t

minMemoryMapAlignment

-

VkDeviceSize

minTexelBufferOffsetAlignment

-

VkDeviceSize

minUniformBufferOffsetAlignment

-

VkDeviceSize

minStorageBufferOffsetAlignment

-

int32_t

minTexelOffset

-

uint32_t

maxTexelOffset

-

int32_t

minTexelGatherOffset

shaderImageGatherExtended

uint32_t

maxTexelGatherOffset

shaderImageGatherExtended

float

minInterpolationOffset

sampleRateShading

float

maxInterpolationOffset

sampleRateShading

uint32_t

subPixelInterpolationOffsetBits

sampleRateShading

uint32_t

maxFramebufferWidth

-

uint32_t

maxFramebufferHeight

-

uint32_t

maxFramebufferLayers

-

VkSampleCountFlags

framebufferColorSampleCounts

-

VkSampleCountFlags

framebufferDepthSampleCounts

-

VkSampleCountFlags

framebufferStencilSampleCounts

-

VkSampleCountFlags

framebufferNoAttachmentsSampleCounts

-

uint32_t

maxColorAttachments

-

VkSampleCountFlags

sampledImageColorSampleCounts

-

VkSampleCountFlags

sampledImageIntegerSampleCounts

-

VkSampleCountFlags

sampledImageDepthSampleCounts

-

VkSampleCountFlags

sampledImageStencilSampleCounts

-

VkSampleCountFlags

storageImageSampleCounts

shaderStorageImageMultisample

uint32_t

maxSampleMaskWords

-

VkBool32

timestampComputeAndGraphics

-

float

timestampPeriod

-

uint32_t

maxClipDistances

shaderClipDistance

uint32_t

maxCullDistances

shaderCullDistance

uint32_t

maxCombinedClipAndCullDistances

shaderCullDistance

uint32_t

discreteQueuePriorities

-

2 = =C3=97 float

pointSizeRange

largePoints

2 = =C3=97 float

lineWidthRange

wideLines

float

pointSizeGranularity

largePoints

float

lineWidthGranularity

wideLines

VkBool32

strictLines

-

VkBool32

standardSampleLocations

-

VkDeviceSize

optimalBufferCopyOffsetAlignment

-

VkDeviceSize

optimalBufferCopyRowPitchAlignment

-

VkDeviceSize

nonCoherentAtomSize

-

uint32_t

maxDiscardRectangles

VK_EXT_discard_rectangles

VkBool32

filterMinmaxSingleComponentFormats

VK_EXT_sampler_filter_minmax

VkBool32

filterMinmaxImageComponentMapping

VK_EXT_sampler_filter_minmax

float

primitiveOverestimationSize

VK_EXT_conservative_rasterization=

VkBool32

maxExtraPrimitiveOverestimationSize

VK_EXT_conservative_rasterization=

float

extraPrimitiveOverestimationSizeGranularity

VK_EXT_conservative_rasterization=

VkBool32

degenerateTriangleRasterized

VK_EXT_conservative_rasterization=

float

degenerateLinesRasterized

VK_EXT_conservative_rasterization=

VkBool32

fullyCoveredFragmentShaderInputVariable

VK_EXT_conservative_rasterization=

VkBool32

conservativeRasterizationPostDepthCoverage

VK_EXT_conservative_rasterization=

uint32_t

maxVertexAttribDivisor

VK_EXT_vertex_attribute_divisor

Table 46. Required Limits
Limit Unsupported Limit Supported Limit Limit Type1

maxImageDimension1D

-

409= 6

min=

maxImageDimension2D

-

409= 6

min=

maxImageDimension3D

-

256=

min=

maxImageDimensionCube

-

409= 6

min=

maxImageArrayLayers

-

256=

min=

maxTexelBufferElements

-

655= 36

min=

maxUniformBufferRange

-

163= 84

min=

maxStorageBufferRange

-

227

min=

maxPushConstantsSize

-

128=

min=

maxMemoryAllocationCount

-

409= 6

min=

maxSamplerAllocationCount

-

400= 0

min=

bufferImageGranularity

-

131= 072

max=

sparseAddressSpaceSize

0

231

min=

maxBoundDescriptorSets

-

4

min=

maxPerStageDescriptorSamplers

-

16<= /p>

min=

maxPerStageDescriptorUniformBuffers

-

12<= /p>

min=

maxPerStageDescriptorStorageBuffers

-

4

min=

maxPerStageDescriptorSampledImages

-

16<= /p>

min=

maxPerStageDescriptorStorageImages

-

4

min=

maxPerStageDescriptorInputAttachments

-

4

min=

maxPerStageResources

-

128= 2

min=

maxDescriptorSetSamplers

-

96 = 8

min= , n =C3=97 PerStage

maxDescriptorSetUniformBuffers

-

72 = 8

min= , n =C3=97 PerStage

maxDescriptorSetUniformBuffersDynamic

-

8

min=

maxDescriptorSetStorageBuffers

-

24 = 8

min= , n =C3=97 PerStage

maxDescriptorSetStorageBuffersDynamic

-

4

min=

maxDescriptorSetSampledImages

-

96 = 8

min= , n =C3=97 PerStage

maxDescriptorSetStorageImages

-

24 = 8

min= , n =C3=97 PerStage

maxDescriptorSetInputAttachments

-

4

min=

maxVertexInputAttributes

-

16<= /p>

min=

maxVertexInputBindings

-

16<= /p>

min=

maxVertexInputAttributeOffset

-

204= 7

min=

maxVertexInputBindingStride

-

204= 8

min=

maxVertexOutputComponents

-

64<= /p>

min=

maxTessellationGenerationLevel

0

64<= /p>

min=

maxTessellationPatchSize

0

32<= /p>

min=

maxTessellationControlPerVertexInputComponents

0

64<= /p>

min=

maxTessellationControlPerVertexOutputComponents

0

64<= /p>

min=

maxTessellationControlPerPatchOutputComponents

0

120=

min=

maxTessellationControlTotalOutputComponents

0

204= 8

min=

maxTessellationEvaluationInputComponents

0

64<= /p>

min=

maxTessellationEvaluationOutputComponents

0

64<= /p>

min=

maxGeometryShaderInvocations

0

32<= /p>

min=

maxGeometryInputComponents

0

64<= /p>

min=

maxGeometryOutputComponents

0

64<= /p>

min=

maxGeometryOutputVertices

0

256=

min=

maxGeometryTotalOutputComponents

0

102= 4

min=

maxFragmentInputComponents

-

64<= /p>

min=

maxFragmentOutputAttachments

-

4

min=

maxFragmentDualSrcAttachments

0

1

min=

maxFragmentCombinedOutputResources

-

4

min=

maxComputeSharedMemorySize

-

163= 84

min=

maxComputeWorkGroupCount

-

(65= 535,65535,65535)

min=

maxComputeWorkGroupInvocations

-

128=

min=

maxComputeWorkGroupSize

-

(12= 8,128,64)

min=

subPixelPrecisionBits

-

4

min=

subTexelPrecisionBits

-

4

min=

mipmapPrecisionBits

-

4

min=

maxDrawIndexedIndexValue

224-1

232-1

min=

maxDrawIndirectCount

1

216-1

min=

maxSamplerLodBias

-

2

min=

maxSamplerAnisotropy

1

16<= /p>

min=

maxViewports

1

16<= /p>

min=

maxViewportDimensions

-

(40= 96,4096) 3

min=

viewportBoundsRange

-

(-8= 192,8191) 4

(ma= x,min)

viewportSubPixelBits

-

0

min=

minMemoryMapAlignment

-

64<= /p>

min=

minTexelBufferOffsetAlignment

-

256=

max=

minUniformBufferOffsetAlignment

-

256=

max=

minStorageBufferOffsetAlignment

-

256=

max=

minTexelOffset

-

-8<= /p>

max=

maxTexelOffset

-

7

min=

minTexelGatherOffset

0

-8<= /p>

max=

maxTexelGatherOffset

0

7

min=

minInterpolationOffset

0.0=

-0.= 5 5

max=

maxInterpolationOffset

0.0=

0.5= - (1 ULP) 5

min=

subPixelInterpolationOffsetBits

0

4 <= sup>5

min=

maxFramebufferWidth

-

409= 6

min=

maxFramebufferHeight

-

409= 6

min=

maxFramebufferLayers

-

256=

min=

framebufferColorSampleCounts

-

(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)

<= /td>

min=

framebufferDepthSampleCounts

-

(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)

<= /td>

min=

framebufferStencilSampleCounts

-

(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)

<= /td>

min=

framebufferNoAttachmentsSampleCounts

-

(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)

<= /td>

min=

maxColorAttachments

-

4

min=

sampledImageColorSampleCounts

-

(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)

<= /td>

min=

sampledImageIntegerSampleCounts

-

VK_SAMPLE_COUNT_1_BIT

min=

sampledImageDepthSampleCounts

-

(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)

<= /td>

min=

sampledImageStencilSampleCounts

-

(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)

<= /td>

min=

storageImageSampleCounts

VK_SAMPLE_COUNT_1_BIT

(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)

<= /td>

min=

maxSampleMaskWords

-

1

min=

timestampComputeAndGraphics

-

-

imp= lementation dependent

timestampPeriod

-

-

dur= ation

maxClipDistances

0

8

min=

maxCullDistances

0

8

min=

maxCombinedClipAndCullDistances

0

8

min=

discreteQueuePriorities

-

2

min=

pointSizeRange

(1.= 0,1.0)

(1.= 0,64.0 - ULP)6

(ma= x,min)

lineWidthRange

(1.= 0,1.0)

(1.= 0,8.0 - ULP)7

(ma= x,min)

pointSizeGranularity

0.0=

1.0= 6

max= , fixed point increment

lineWidthGranularity

0.0=

1.0= 7

max= , fixed point increment

strictLines

-

-

imp= lementation dependent

standardSampleLocations

-

-

imp= lementation dependent

optimalBufferCopyOffsetAlignment

-

-

rec= ommendation

optimalBufferCopyRowPitchAlignment

-

-

rec= ommendation

nonCoherentAtomSize

-

256=

max=

maxPushDescriptors

-

32<= /p>

min=

maxMultiviewViewCount

-

6

min=

maxMultiviewInstanceIndex

-

227-1

min=

maxDiscardRectangles

0

4

min=

sampleLocationSampleCounts

-

VK_SAMPLE_COUNT_4_BIT

min=

maxSampleLocationGridSize

-

(1,= 1)

min=

sampleLocationCoordinateRange

-

(0.= 0, 0.9375)

(ma= x,min)

sampleLocationSubPixelBits

-

4

min=

variableSampleLocations

-

fal= se

imp= lementation dependent

minImportedHostPointerAlignment

-

655= 36

max=

perViewPositionAllComponents

-

-

imp= lementation dependent

filterMinmaxSingleComponentFormats

-

-

imp= lementation dependent

filterMinmaxImageComponentMapping

-

-

imp= lementation dependent

advancedBlendMaxColorAttachments

-

1

min=

advancedBlendIndependentBlend

-

fal= se

imp= lementation dependent

advancedBlendNonPremultipliedSrcColor

-

fal= se

imp= lementation dependent

advancedBlendNonPremultipliedDstColor

-

fal= se

imp= lementation dependent

advancedBlendCorrelatedOverlap

-

fal= se

imp= lementation dependent

advancedBlendAllOperations

-

fal= se

imp= lementation dependent

maxPerSetDescriptors

-

102= 4

min=

maxMemoryAllocationSize

-

230

min=

primitiveOverestimationSize

-

0.0=

min=

maxExtraPrimitiveOverestimationSize

-

0.0=

min=

extraPrimitiveOverestimationSizeGranularity

-

0.0=

min=

primitiveUnderestimation

-

fal= se

imp= lementation dependent

conservativePointAndLineRasterization

-

fal= se

imp= lementation dependent

degenerateTrianglesRasterized

-

fal= se

imp= lementation dependent

degenerateLinesRasterized

-

fal= se

imp= lementation dependent

fullyCoveredFragmentShaderInputVariable

-

fal= se

imp= lementation dependent

conservativeRasterizationPostDepthCoverage

-

fal= se

imp= lementation dependent

maxUpdateAfterBindDescriptorsInAllPools

-

500= 000

min=

shaderUniformBufferArrayNonUniformIndexingNative

-

fal= se

imp= lementation dependent

shaderSampledImageArrayNonUniformIndexingNative

-

fal= se

imp= lementation dependent

shaderStorageBufferArrayNonUniformIndexingNative

-

fal= se

imp= lementation dependent

shaderStorageImageArrayNonUniformIndexingNative

-

fal= se

imp= lementation dependent

shaderInputAttachmentArrayNonUniformIndexingNative

-

fal= se

imp= lementation dependent

maxPerStageDescriptorUpdateAfterBindSamplers

-

500= 000 9

min=

maxPerStageDescriptorUpdateAfterBindUniformBuffers

-

12 = 9

min=

maxPerStageDescriptorUpdateAfterBindStorageBuffers

-

500= 000 9

min=

maxPerStageDescriptorUpdateAfterBindSampledImages

-

500= 000 9

min=

maxPerStageDescriptorUpdateAfterBindStorageImages

-

500= 000 9

min=

maxPerStageDescriptorUpdateAfterBindInputAttachments

-

500= 000 9

min=

maxPerStageUpdateAfterBindResources

-

500= 000 9

min=

maxDescriptorSetUpdateAfterBindSamplers

-

500= 000 9

min=

maxDescriptorSetUpdateAfterBindUniformBuffers

-

72 = 8 9

min= , n =C3=97 PerStage

maxDescriptorSetUpdateAfterBindUniformBuffersDynamic

-

8 <= sup>9

min=

maxDescriptorSetUpdateAfterBindStorageBuffers

-

500= 000 9

min=

maxDescriptorSetUpdateAfterBindStorageBuffersDynamic

-

4 <= sup>9

min=

maxDescriptorSetUpdateAfterBindSampledImages

-

500= 000 9

min=

maxDescriptorSetUpdateAfterBindStorageImages

-

500= 000 9

min=

maxDescriptorSetUpdateAfterBindInputAttachments

-

500= 000 9

min=

maxVertexAttribDivisor

-

216-1

min=

1

The Limit Type column specifies the limit is either the= minimum limit all implementations must support or the m= aximum limit all implementations must support. For bitmasks a minimum limit is the least bits all implementations must set, but they may have additional bits se= t beyond this minimum.

2

The maxPerStageResources must be at least the smallest of the following:

  • the sum of the maxPerStageDescriptorUniformBuffers, maxPerStageDescriptorStorageBuffers, maxPerStageDescriptorSampledImages, maxPerStageDescriptorStorageImages, maxPerStageDescriptorInputAttachments, maxColorAttachmen= ts limits, or

  • 128.

It may not be possible to reach this l= imit in every stage.

3

See maxViewportDimensions for the required relationship to other li= mits.

4

See viewportBoundsRange for the required relationship to other li= mits.

5

The values minInterpolationOffset and maxInterpolatio= nOffset describe the closed interval of supported interpolation offsets: [minInterpolationOffset, maxInterpolationOffset]. The ULP is determined by subPixelInterpolationOffsetBits. If subPixelInterpolationOffsetBits is 4, this provides increme= nts of (1/24) =3D 0.0625, and thus the range of supported interpolat= ion offsets would be [-0.5, 0.4375].

6

The point size ULP is determined by pointSizeGranularity. If the pointSizeGranularity is 0.125, the range of supported p= oint sizes must be at least [1.0, 63.875].

7

The line width ULP is determined by lineWidthGranularity. If the lineWidthGranularity is 0.0625, the range of supported = line widths must be at least [1.0, 7.9375].

8

The minimum maxDescriptorSet* limit is n times the= corresponding specification minimum maxPerStageDescriptor* limit, w= here n is the number of shader stages supported by the VkPhysicalDe= vice. If all shader stages are supported, n =3D 6 (vertex, tessellation control, tessellation evaluation, geometry, fragment, compute).

9

The UpdateAfterBind descriptor limits must each be greater than or equal to the corresponding non-UpdateAfterBind limit.

32.3. Additional Multisampling Capab= ilities

In addition to the minimum capabilities described in the previous sectio= n (Limits), implementations may= support additional multisampling capabilities specific to a particular sample count.

To query additional sample count specific multisampling capabilities, ca= ll:

void vkGetPhysicalDeviceMultisamplePropertiesEXT(
    VkPhysicalDevice                            physicalDevice,
    VkSampleCountFlagBits                       samples,
    VkMultisamplePropertiesEXT*                 pMultisampleProperties);
  • physicalDevice is the physical device from which to query t= he additional multisampling capabilities.

  • samples is the sample count to query the capabilities for.<= /p>

  • pMultisampleProperties is a pointer to a structure of type VkMultisamplePropertiesEXT, in which inform= ation about the additional multisampling capabilities specific to the sample count is returned.

Valid Usage (Implicit)
  • physicalDevice must<= /strong> be a valid VkPhysicalDevice handle

  • samples must be a = valid VkSampleCountFlagBits value

  • pMultisampleProperties must be a valid pointer to a VkMultisampleProper= tiesEXT structure

The VkMultisamplePropertiesEXT structure is defined as

typedef struct VkMultisamplePro=
pertiesEXT {
    VkStructureType    sType;
    void*              pNext;
    VkExtent2D         maxSampleLocationGridSize;
} VkMultisamplePropertiesEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • maxSampleLocationGridSize is the maximum size of the pixel = grid in which sample locations can vary.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_MUL= TISAMPLE_PROPERTIES_EXT

  • pNext must be NULL

If the sample count for which additional multisampling capabilities are requested using vkGetPhysicalDeviceMultisamplePropertiesEXT is= set in VkPhysicalDeviceSampleLocationsEXT:: sampleLocationSampleCount= s the width and height members of VkMultisamplePropertiesEXT::maxSampleLocationGridSize= must be greater than or equal to the corresponding members of VkPhysicalDeviceSampleLocationsEXT:: maxSampleLocationGridSize<= /code>, respectively, otherwise both members must= be 0.

32.4. Formats

The features for the set of formats (VkFormat) supported b= y the implementation are queried individually using the vkGetPhysicalDeviceFormatProperties command.

32.4.1. Format Definition

Image formats which can be passed to, = and may be returned from Vulkan commands, are:

typedef enum VkFormat {
    VK_FORMAT_UNDEFINED =3D 0,
    VK_FORMAT_R4G4_UNORM_PACK8 =3D 1,
    VK_FORMAT_R4G4B4A4_UNORM_PACK16 =3D 2,
    VK_FORMAT_B4G4R4A4_UNORM_PACK16 =3D 3,
    VK_FORMAT_R5G6B5_UNORM_PACK16 =3D 4,
    VK_FORMAT_B5G6R5_UNORM_PACK16 =3D 5,
    VK_FORMAT_R5G5B5A1_UNORM_PACK16 =3D 6,
    VK_FORMAT_B5G5R5A1_UNORM_PACK16 =3D 7,
    VK_FORMAT_A1R5G5B5_UNORM_PACK16 =3D 8,
    VK_FORMAT_R8_UNORM =3D 9,
    VK_FORMAT_R8_SNORM =3D 10,
    VK_FORMAT_R8_USCALED =3D 11,
    VK_FORMAT_R8_SSCALED =3D 12,
    VK_FORMAT_R8_UINT =3D 13,
    VK_FORMAT_R8_SINT =3D 14,
    VK_FORMAT_R8_SRGB =3D 15,
    VK_FORMAT_R8G8_UNORM =3D 16,
    VK_FORMAT_R8G8_SNORM =3D 17,
    VK_FORMAT_R8G8_USCALED =3D 18,
    VK_FORMAT_R8G8_SSCALED =3D 19,
    VK_FORMAT_R8G8_UINT =3D 20,
    VK_FORMAT_R8G8_SINT =3D 21,
    VK_FORMAT_R8G8_SRGB =3D 22,
    VK_FORMAT_R8G8B8_UNORM =3D 23,
    VK_FORMAT_R8G8B8_SNORM =3D 24,
    VK_FORMAT_R8G8B8_USCALED =3D 25,
    VK_FORMAT_R8G8B8_SSCALED =3D 26,
    VK_FORMAT_R8G8B8_UINT =3D 27,
    VK_FORMAT_R8G8B8_SINT =3D 28,
    VK_FORMAT_R8G8B8_SRGB =3D 29,
    VK_FORMAT_B8G8R8_UNORM =3D 30,
    VK_FORMAT_B8G8R8_SNORM =3D 31,
    VK_FORMAT_B8G8R8_USCALED =3D 32,
    VK_FORMAT_B8G8R8_SSCALED =3D 33,
    VK_FORMAT_B8G8R8_UINT =3D 34,
    VK_FORMAT_B8G8R8_SINT =3D 35,
    VK_FORMAT_B8G8R8_SRGB =3D 36,
    VK_FORMAT_R8G8B8A8_UNORM =3D 37,
    VK_FORMAT_R8G8B8A8_SNORM =3D 38,
    VK_FORMAT_R8G8B8A8_USCALED =3D 39,
    VK_FORMAT_R8G8B8A8_SSCALED =3D 40,
    VK_FORMAT_R8G8B8A8_UINT =3D 41,
    VK_FORMAT_R8G8B8A8_SINT =3D 42,
    VK_FORMAT_R8G8B8A8_SRGB =3D 43,
    VK_FORMAT_B8G8R8A8_UNORM =3D 44,
    VK_FORMAT_B8G8R8A8_SNORM =3D 45,
    VK_FORMAT_B8G8R8A8_USCALED =3D 46,
    VK_FORMAT_B8G8R8A8_SSCALED =3D 47,
    VK_FORMAT_B8G8R8A8_UINT =3D 48,
    VK_FORMAT_B8G8R8A8_SINT =3D 49,
    VK_FORMAT_B8G8R8A8_SRGB =3D 50,
    VK_FORMAT_A8B8G8R8_UNORM_PACK32 =3D 51,
    VK_FORMAT_A8B8G8R8_SNORM_PACK32 =3D 52,
    VK_FORMAT_A8B8G8R8_USCALED_PACK32 =3D 53=
,
    VK_FORMAT_A8B8G8R8_SSCALED_PACK32 =3D 54=
,
    VK_FORMAT_A8B8G8R8_UINT_PACK32 =3D 55,
    VK_FORMAT_A8B8G8R8_SINT_PACK32 =3D 56,
    VK_FORMAT_A8B8G8R8_SRGB_PACK32 =3D 57,
    VK_FORMAT_A2R10G10B10_UNORM_PACK32 =3D 58,
    VK_FORMAT_A2R10G10B10_SNORM_PACK32 =3D 59,
    VK_FORMAT_A2R10G10B10_USCALED_PACK32 =3D 60,
    VK_FORMAT_A2R10G10B10_SSCALED_PACK32 =3D 61,
    VK_FORMAT_A2R10G10B10_UINT_PACK32 =3D 62=
,
    VK_FORMAT_A2R10G10B10_SINT_PACK32 =3D 63=
,
    VK_FORMAT_A2B10G10R10_UNORM_PACK32 =3D 64,
    VK_FORMAT_A2B10G10R10_SNORM_PACK32 =3D 65,
    VK_FORMAT_A2B10G10R10_USCALED_PACK32 =3D 66,
    VK_FORMAT_A2B10G10R10_SSCALED_PACK32 =3D 67,
    VK_FORMAT_A2B10G10R10_UINT_PACK32 =3D 68=
,
    VK_FORMAT_A2B10G10R10_SINT_PACK32 =3D 69=
,
    VK_FORMAT_R16_UNORM =3D 70,
    VK_FORMAT_R16_SNORM =3D 71,
    VK_FORMAT_R16_USCALED =3D 72,
    VK_FORMAT_R16_SSCALED =3D 73,
    VK_FORMAT_R16_UINT =3D 74,
    VK_FORMAT_R16_SINT =3D 75,
    VK_FORMAT_R16_SFLOAT =3D 76,
    VK_FORMAT_R16G16_UNORM =3D 77,
    VK_FORMAT_R16G16_SNORM =3D 78,
    VK_FORMAT_R16G16_USCALED =3D 79,
    VK_FORMAT_R16G16_SSCALED =3D 80,
    VK_FORMAT_R16G16_UINT =3D 81,
    VK_FORMAT_R16G16_SINT =3D 82,
    VK_FORMAT_R16G16_SFLOAT =3D 83,
    VK_FORMAT_R16G16B16_UNORM =3D 84,
    VK_FORMAT_R16G16B16_SNORM =3D 85,
    VK_FORMAT_R16G16B16_USCALED =3D 86,
    VK_FORMAT_R16G16B16_SSCALED =3D 87,
    VK_FORMAT_R16G16B16_UINT =3D 88,
    VK_FORMAT_R16G16B16_SINT =3D 89,
    VK_FORMAT_R16G16B16_SFLOAT =3D 90,
    VK_FORMAT_R16G16B16A16_UNORM =3D 91,
    VK_FORMAT_R16G16B16A16_SNORM =3D 92,
    VK_FORMAT_R16G16B16A16_USCALED =3D 93,
    VK_FORMAT_R16G16B16A16_SSCALED =3D 94,
    VK_FORMAT_R16G16B16A16_UINT =3D 95,
    VK_FORMAT_R16G16B16A16_SINT =3D 96,
    VK_FORMAT_R16G16B16A16_SFLOAT =3D 97,
    VK_FORMAT_R32_UINT =3D 98,
    VK_FORMAT_R32_SINT =3D 99,
    VK_FORMAT_R32_SFLOAT =3D 100,
    VK_FORMAT_R32G32_UINT =3D 101,
    VK_FORMAT_R32G32_SINT =3D 102,
    VK_FORMAT_R32G32_SFLOAT =3D 103,
    VK_FORMAT_R32G32B32_UINT =3D 104,
    VK_FORMAT_R32G32B32_SINT =3D 105,
    VK_FORMAT_R32G32B32_SFLOAT =3D 106,
    VK_FORMAT_R32G32B32A32_UINT =3D 107,
    VK_FORMAT_R32G32B32A32_SINT =3D 108,
    VK_FORMAT_R32G32B32A32_SFLOAT =3D 109,
    VK_FORMAT_R64_UINT =3D 110,
    VK_FORMAT_R64_SINT =3D 111,
    VK_FORMAT_R64_SFLOAT =3D 112,
    VK_FORMAT_R64G64_UINT =3D 113,
    VK_FORMAT_R64G64_SINT =3D 114,
    VK_FORMAT_R64G64_SFLOAT =3D 115,
    VK_FORMAT_R64G64B64_UINT =3D 116,
    VK_FORMAT_R64G64B64_SINT =3D 117,
    VK_FORMAT_R64G64B64_SFLOAT =3D 118,
    VK_FORMAT_R64G64B64A64_UINT =3D 119,
    VK_FORMAT_R64G64B64A64_SINT =3D 120,
    VK_FORMAT_R64G64B64A64_SFLOAT =3D 121,
    VK_FORMAT_B10G11R11_UFLOAT_PACK32 =3D 122,
    VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 =3D 123=
,
    VK_FORMAT_D16_UNORM =3D 124,
    VK_FORMAT_X8_D24_UNORM_PACK32 =3D 125,
    VK_FORMAT_D32_SFLOAT =3D 126,
    VK_FORMAT_S8_UINT =3D 127,
    VK_FORMAT_D16_UNORM_S8_UINT =3D 128,
    VK_FORMAT_D24_UNORM_S8_UINT =3D 129,
    VK_FORMAT_D32_SFLOAT_S8_UINT =3D 130,
    VK_FORMAT_BC1_RGB_UNORM_BLOCK =3D 131,
    VK_FORMAT_BC1_RGB_SRGB_BLOCK =3D 132,
    VK_FORMAT_BC1_RGBA_UNORM_BLOCK =3D 133,
    VK_FORMAT_BC1_RGBA_SRGB_BLOCK =3D 134,
    VK_FORMAT_BC2_UNORM_BLOCK =3D 135,
    VK_FORMAT_BC2_SRGB_BLOCK =3D 136,
    VK_FORMAT_BC3_UNORM_BLOCK =3D 137,
    VK_FORMAT_BC3_SRGB_BLOCK =3D 138,
    VK_FORMAT_BC4_UNORM_BLOCK =3D 139,
    VK_FORMAT_BC4_SNORM_BLOCK =3D 140,
    VK_FORMAT_BC5_UNORM_BLOCK =3D 141,
    VK_FORMAT_BC5_SNORM_BLOCK =3D 142,
    VK_FORMAT_BC6H_UFLOAT_BLOCK =3D 143,
    VK_FORMAT_BC6H_SFLOAT_BLOCK =3D 144,
    VK_FORMAT_BC7_UNORM_BLOCK =3D 145,
    VK_FORMAT_BC7_SRGB_BLOCK =3D 146,
    VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK =3D 147,
    VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK =3D 148=
,
    VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK =3D 149,
    VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK =3D 150,
    VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK =3D 151,
    VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK =3D 152,
    VK_FORMAT_EAC_R11_UNORM_BLOCK =3D 153,
    VK_FORMAT_EAC_R11_SNORM_BLOCK =3D 154,
    VK_FORMAT_EAC_R11G11_UNORM_BLOCK =3D 155=
,
    VK_FORMAT_EAC_R11G11_SNORM_BLOCK =3D 156=
,
    VK_FORMAT_ASTC_4x4_UNORM_BLOCK =3D 157,
    VK_FORMAT_ASTC_4x4_SRGB_BLOCK =3D 158,
    VK_FORMAT_ASTC_5x4_UNORM_BLOCK =3D 159,
    VK_FORMAT_ASTC_5x4_SRGB_BLOCK =3D 160,
    VK_FORMAT_ASTC_5x5_UNORM_BLOCK =3D 161,
    VK_FORMAT_ASTC_5x5_SRGB_BLOCK =3D 162,
    VK_FORMAT_ASTC_6x5_UNORM_BLOCK =3D 163,
    VK_FORMAT_ASTC_6x5_SRGB_BLOCK =3D 164,
    VK_FORMAT_ASTC_6x6_UNORM_BLOCK =3D 165,
    VK_FORMAT_ASTC_6x6_SRGB_BLOCK =3D 166,
    VK_FORMAT_ASTC_8x5_UNORM_BLOCK =3D 167,
    VK_FORMAT_ASTC_8x5_SRGB_BLOCK =3D 168,
    VK_FORMAT_ASTC_8x6_UNORM_BLOCK =3D 169,
    VK_FORMAT_ASTC_8x6_SRGB_BLOCK =3D 170,
    VK_FORMAT_ASTC_8x8_UNORM_BLOCK =3D 171,
    VK_FORMAT_ASTC_8x8_SRGB_BLOCK =3D 172,
    VK_FORMAT_ASTC_10x5_UNORM_BLOCK =3D 173,
    VK_FORMAT_ASTC_10x5_SRGB_BLOCK =3D 174,
    VK_FORMAT_ASTC_10x6_UNORM_BLOCK =3D 175,
    VK_FORMAT_ASTC_10x6_SRGB_BLOCK =3D 176,
    VK_FORMAT_ASTC_10x8_UNORM_BLOCK =3D 177,
    VK_FORMAT_ASTC_10x8_SRGB_BLOCK =3D 178,
    VK_FORMAT_ASTC_10x10_UNORM_BLOCK =3D 179=
,
    VK_FORMAT_ASTC_10x10_SRGB_BLOCK =3D 180,
    VK_FORMAT_ASTC_12x10_UNORM_BLOCK =3D 181=
,
    VK_FORMAT_ASTC_12x10_SRGB_BLOCK =3D 182,
    VK_FORMAT_ASTC_12x12_UNORM_BLOCK =3D 183=
,
    VK_FORMAT_ASTC_12x12_SRGB_BLOCK =3D 184,
    VK_FORMAT_G8B8G8R8_422_UNORM =3D 1000156000,
    VK_FORMAT_B8G8R8G8_422_UNORM =3D 1000156001,
    VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM =3D 1000156=
002,
    VK_FORMAT_G8_B8R8_2PLANE_420_UNORM =3D 10001560=
03,
    VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM =3D 1000156=
004,
    VK_FORMAT_G8_B8R8_2PLANE_422_UNORM =3D 10001560=
05,
    VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM =3D 1000156=
006,
    VK_FORMAT_R10X6_UNORM_PACK16 =3D 1000156007,
    VK_FORMAT_R10X6G10X6_UNORM_2PACK16 =3D 10001560=
08,
    VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 =3D 1000156009,
    VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 =3D 1000156010,
    VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 =3D 1000156011,
    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 =3D 1000156012,
    VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 =3D 1000156013,
    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 =3D 1000156014,
    VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 =3D 1000156015,
    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 =3D 1000156016,
    VK_FORMAT_R12X4_UNORM_PACK16 =3D 1000156017,
    VK_FORMAT_R12X4G12X4_UNORM_2PACK16 =3D 10001560=
18,
    VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 =3D 1000156019,
    VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 =3D 1000156020,
    VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 =3D 1000156021,
    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 =3D 1000156022,
    VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 =3D 1000156023,
    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 =3D 1000156024,
    VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 =3D 1000156025,
    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 =3D 1000156026,
    VK_FORMAT_G16B16G16R16_422_UNORM =3D 1000156027=
,
    VK_FORMAT_B16G16R16G16_422_UNORM =3D 1000156028=
,
    VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM =3D 1000=
156029,
    VK_FORMAT_G16_B16R16_2PLANE_420_UNORM =3D 10001=
56030,
    VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM =3D 1000=
156031,
    VK_FORMAT_G16_B16R16_2PLANE_422_UNORM =3D 10001=
56032,
    VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM =3D 1000=
156033,
    VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG =3D 10000=
54000,
    VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG =3D 10000=
54001,
    VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG =3D 10000=
54002,
    VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG =3D 10000=
54003,
    VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG =3D 100005=
4004,
    VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG =3D 100005=
4005,
    VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG =3D 100005=
4006,
    VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG =3D 100005=
4007,
    VK_FORMAT_G8B8G8R8_422_UNORM_KHR =3D VK_FORMAT_G8B8G8R8_422_UNORM,
    VK_FORMAT_B8G8R8G8_422_UNORM_KHR =3D VK_FORMAT_B8G8R8G8_422_UNORM,
    VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR =3D VK_FORMAT_G8_B8_R8_3PLANE_4=
20_UNORM,
    VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR =3D VK_FORMAT_G8_B8R8_2PLANE_420=
_UNORM,
    VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR =3D VK_FORMAT_G8_B8_R8_3PLANE_4=
22_UNORM,
    VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR =3D VK_FORMAT_G8_B8R8_2PLANE_422=
_UNORM,
    VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR =3D VK_FORMAT_G8_B8_R8_3PLANE_4=
44_UNORM,
    VK_FORMAT_R10X6_UNORM_PACK16_KHR =3D VK_FORMAT_R10X6_UNORM_PACK16,
    VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR =3D VK_FORMAT_R10X6G10X6_UNORM_2=
PACK16,
    VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR =3D VK_FORMAT_R10X6G10=
X6B10X6A10X6_UNORM_4PACK16,
    VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR =3D VK_FORMAT_G10X=
6B10X6G10X6R10X6_422_UNORM_4PACK16,
    VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR =3D VK_FORMAT_B10X=
6G10X6R10X6G10X6_422_UNORM_4PACK16,
    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR =3D VK_FORMAT_=
G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
    VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR =3D VK_FORMAT_G=
10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR =3D VK_FORMAT_=
G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
    VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR =3D VK_FORMAT_G=
10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
    VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR =3D VK_FORMAT_=
G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
    VK_FORMAT_R12X4_UNORM_PACK16_KHR =3D VK_FORMAT_R12X4_UNORM_PACK16,
    VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR =3D VK_FORMAT_R12X4G12X4_UNORM_2=
PACK16,
    VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR =3D VK_FORMAT_R12X4G12=
X4B12X4A12X4_UNORM_4PACK16,
    VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR =3D VK_FORMAT_G12X=
4B12X4G12X4R12X4_422_UNORM_4PACK16,
    VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR =3D VK_FORMAT_B12X=
4G12X4R12X4G12X4_422_UNORM_4PACK16,
    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR =3D VK_FORMAT_=
G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
    VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR =3D VK_FORMAT_G=
12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR =3D VK_FORMAT_=
G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
    VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR =3D VK_FORMAT_G=
12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
    VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR =3D VK_FORMAT_=
G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
    VK_FORMAT_G16B16G16R16_422_UNORM_KHR =3D VK_FORMAT_G16B16G16R16_422_UNO=
RM,
    VK_FORMAT_B16G16R16G16_422_UNORM_KHR =3D VK_FORMAT_B16G16R16G16_422_UNO=
RM,
    VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR =3D VK_FORMAT_G16_B16_R16_3P=
LANE_420_UNORM,
    VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR =3D VK_FORMAT_G16_B16R16_2PLA=
NE_420_UNORM,
    VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR =3D VK_FORMAT_G16_B16_R16_3P=
LANE_422_UNORM,
    VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR =3D VK_FORMAT_G16_B16R16_2PLA=
NE_422_UNORM,
    VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR =3D VK_FORMAT_G16_B16_R16_3P=
LANE_444_UNORM,
} VkFormat;
Compatible formats of planes = of multi-planar formats

Individual planes of multi-planar formats are compatible with s= ingle-plane formats if they occupy the same number of bits per data element. In the following table, individual planes of a multi-planar format= are compatible with the format listed against the relevant plane index for that multi-planar format.

Table 47. Plane Format Compatibility Table
Plane Compatible format for pla= ne Width relative to the wid= th w of the plane with the largest dimensions Height relative to the he= ight h of the plane with the largest dimensions

VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM

0=

<= code>VK_FORMAT_R8_UNORM

w=

h=

1=

<= code>VK_FORMAT_R8_UNORM

w= /2

h= /2

2=

<= code>VK_FORMAT_R8_UNORM

w= /2

h= /2

VK_FORMAT_G8_B8R8_2PLANE_420_UNORM=

0=

<= code>VK_FORMAT_R8_UNORM

w=

h=

1=

<= code>VK_FORMAT_R8G8_UNORM

w= /2

h= /2

VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM

0=

<= code>VK_FORMAT_R8_UNORM

w=

h=

1=

<= code>VK_FORMAT_R8_UNORM

w= /2

h=

2=

<= code>VK_FORMAT_R8_UNORM

w= /2

h=

VK_FORMAT_G8_B8R8_2PLANE_422_UNORM=

0=

<= code>VK_FORMAT_R8_UNORM

w=

h=

1=

<= code>VK_FORMAT_R8G8_UNORM

w= /2

h=

VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM

0=

<= code>VK_FORMAT_R8_UNORM

w=

h=

1=

<= code>VK_FORMAT_R8_UNORM

w=

h=

2=

<= code>VK_FORMAT_R8_UNORM

w=

h=

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK= 16

0=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w= /2

h= /2

2=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w= /2

h= /2

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK1= 6

0=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R10X6G10X6_UNORM_2PACK16

w= /2

h= /2

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK= 16

0=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w= /2

h=

2=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w= /2

h=

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK1= 6

0=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R10X6G10X6_UNORM_2PACK16

w= /2

h=

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK= 16

0=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w=

h=

2=

<= code>VK_FORMAT_R10X6_UNORM_PACK16

w=

h=

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK= 16

0=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w= /2

h= /2

2=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w= /2

h= /2

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK1= 6

0=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R12X4G12X4_UNORM_2PACK16

w= /2

h= /2

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK= 16

0=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w= /2

h=

2=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w= /2

h=

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK1= 6

0=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R12X4G12X4_UNORM_2PACK16

w= /2

h=

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK= 16

0=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w=

h=

1=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w=

h=

2=

<= code>VK_FORMAT_R12X4_UNORM_PACK16

w=

h=

VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM

0=

<= code>VK_FORMAT_R16_UNORM

w=

h=

1=

<= code>VK_FORMAT_R16_UNORM

w= /2

h= /2

2=

<= code>VK_FORMAT_R16_UNORM

w= /2

h= /2

VK_FORMAT_G16_B16R16_2PLANE_420_UNORM

0=

<= code>VK_FORMAT_R16_UNORM

w=

h=

1=

<= code>VK_FORMAT_R16G16_UNORM

w= /2

h= /2

VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM

0=

<= code>VK_FORMAT_R16_UNORM

w=

h=

1=

<= code>VK_FORMAT_R16_UNORM

w= /2

h=

2=

<= code>VK_FORMAT_R16_UNORM

w= /2

h=

VK_FORMAT_G16_B16R16_2PLANE_422_UNORM

0=

<= code>VK_FORMAT_R16_UNORM

w=

h=

1=

<= code>VK_FORMAT_R16G16_UNORM

w= /2

h=

VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM

0=

<= code>VK_FORMAT_R16_UNORM

w=

h=

1=

<= code>VK_FORMAT_R16_UNORM

w=

h=

2=

<= code>VK_FORMAT_R16_UNORM

w=

h=

Packed Formats

For the purposes of address alignment when accessing buffer memory containing vertex attribute or texel data, the following formats are considered packed - whole texels or attributes are stored in a sin= gle data element, rather than individual components occupying a single data element:=

  • Packed into 8-bit data types:

    • VK_FORMAT_R4G4_UNORM_PACK8

  • Packed into 16-bit data types:

    • VK_FORMAT_R4G4B4A4_UNORM_PACK16

    • VK_FORMAT_B4G4R4A4_UNORM_PACK16

    • VK_FORMAT_R5G6B5_UNORM_PACK16

    • VK_FORMAT_B5G6R5_UNORM_PACK16

    • VK_FORMAT_R5G5B5A1_UNORM_PACK16

    • VK_FORMAT_B5G5R5A1_UNORM_PACK16

    • VK_FORMAT_A1R5G5B5_UNORM_PACK16

  • Packed into 32-bit data types:

    • VK_FORMAT_A8B8G8R8_UNORM_PACK32

    • VK_FORMAT_A8B8G8R8_SNORM_PACK32

    • VK_FORMAT_A8B8G8R8_USCALED_PACK32

    • VK_FORMAT_A8B8G8R8_SSCALED_PACK32

    • VK_FORMAT_A8B8G8R8_UINT_PACK32

    • VK_FORMAT_A8B8G8R8_SINT_PACK32

    • VK_FORMAT_A8B8G8R8_SRGB_PACK32

    • VK_FORMAT_A2R10G10B10_UNORM_PACK32

    • VK_FORMAT_A2R10G10B10_SNORM_PACK32

    • VK_FORMAT_A2R10G10B10_USCALED_PACK32

    • VK_FORMAT_A2R10G10B10_SSCALED_PACK32

    • VK_FORMAT_A2R10G10B10_UINT_PACK32

    • VK_FORMAT_A2R10G10B10_SINT_PACK32

    • VK_FORMAT_A2B10G10R10_UNORM_PACK32

    • VK_FORMAT_A2B10G10R10_SNORM_PACK32

    • VK_FORMAT_A2B10G10R10_USCALED_PACK32

    • VK_FORMAT_A2B10G10R10_SSCALED_PACK32

    • VK_FORMAT_A2B10G10R10_UINT_PACK32

    • VK_FORMAT_A2B10G10R10_SINT_PACK32

    • VK_FORMAT_B10G11R11_UFLOAT_PACK32

    • VK_FORMAT_E5B9G9R9_UFLOAT_PACK32

    • VK_FORMAT_X8_D24_UNORM_PACK32

Identification of Formats

A =E2=80=9Cformat=E2=80=9D is represented by a single enum value. The name of a format is usually built up by using the following pattern:

    VK_FORMAT_{component-format|compression-scheme}_{numeric-format}

The component-format indicates either the size of the R, G, B, and A components (if they are present) in the case of a color format, or the size of the depth (D) and stencil (S) components (if they are present) in the case of a depth/stencil format (see below). An X indicates a component that is unused, but may= be present for padding.

Table 48. Interpretation of Numeric Format
Numeric format Description

UNORM

The= components are unsigned normalized values in the range = [0,1]

SNORM

The= components are signed normalized values in the range [-= 1,1]

USCALED

The= components are unsigned integer values that get converted to floating-poin= t in the range [0,2n-1]

SSCALED

The= components are signed integer values that get converted to floating-point = in the range [-2n-1,2n-1-1]

UINT

The= components are unsigned integer values in the range [0,2n-1]

SINT

The= components are signed integer values in the range [-2n-1,2= n-1-1]

UFLOAT

The= components are unsigned floating-point numbers (used by packed, shared exp= onent, and some compressed formats)

SFLOAT

The= components are signed floating-point numbers

SRGB

The= R, G, and B components are unsigned normalized values that represent value= s using sRGB nonlinear encoding, while the A component (if one exists) is a= regular unsigned normalized value

The suffix _PACKnn indicates that the format is packed into= an underlying type with nn bits. The suffix _mPACKnn is a short-hand that indicates that the fo= rmat has several components (which may or may not be stored in separate planes) that are each packed into an underlying type with nn bits.

The suffix _BLOCK indicates that the format is a block-comp= ressed format, with the representation of multiple pixels encoded interdependently within a region.

Table 49. Interpretation of Compression Scheme
Compression scheme Description

BC

Blo= ck Compression. See Block-Compressed Image Forma= ts.

ETC2

Eri= csson Texture Compression. See ETC Compressed = Image Formats.

EAC

ETC= 2 Alpha Compression. See ETC Compressed Image = Formats.

ASTC

Ada= ptive Scalable Texture Compression (LDR Profile). See ASTC Compressed Image Formats.

For multi-planar images, the components in separate planes<= /em> are separated by underscores, and the number of planes is indicated by the addition of a _2PLANE or _3PLANE suffix. Similarly, the separate aspects of depth-stencil formats are separated by underscores, although these are not considered separate planes. Formats are suffixed by _422 to indicate that planes other tha= n the first are reduced in size by a factor of two horizontally or that the R and B values appear at half the horizontal frequency of the G values, _42= 0 to indicate that planes other than the first are reduced in size by a facto= r of two both horizontally and vertically, and _444 for consiste= ncy to indicate that all three planes of a three-planar image are the same size.

Note

No common format has a single plane containing both R and B channels but does not store these channels at reduced horizontal resolution.

Representation

Color formats must be represented in m= emory in exactly the form indicated by the format=E2=80=99s name. This means that promoting one format to another with more bits per componen= t and/or additional components must not occ= ur for color formats. Depth/stencil formats have more relaxed requirements as discussed below. Each format has an element size, the number of bytes used to store= d one element or one compressed block, with the value of the element size listed in VkFormat.

The representation of non-packed formats is that the first component specified in the name of the format is in the lowest memory addresses and the last component specified is in the highest memory addresses. See Byte mappings for non-packed/compressed color formats. The in-memory ordering of bytes within a component is determined by the hos= t endianness.

Table 50. Byte mappings for non-packed/compressed = color formats
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 =E2=86=90 Byte

R=

VK_FORMAT_R8_*

R=

G=

VK_FORMAT_R8G8_*

R=

G=

B=

VK_FORMAT_R8G8B8_*

B=

G=

R=

VK_FORMAT_B8G8R8_*

R=

G=

B=

A=

VK_FORMAT_R8G8B8A8_*

B=

G=

R=

A=

VK_FORMAT_B8G8R8A8_*

G= 0

B=

G= 1

R=

VK_FORMAT_G8B8G8R8_422_UNORM

=

B=

G= 0

R=

G= 1

VK_FORMAT_B8G8R8G8_422_UNORM

=

R

VK_FORMAT_R16_*

R

G

VK_FORMAT_R16G16_*

R

G

B

VK_FORMAT_R16G16B16_*

R

G

B

A

VK_FORMAT_R16G16B16A16_*

G0

B

G1

R

VK_FORMAT_G10X6B10X6G10X6R10X6_4PACK16_422_UNORM<= /code> VK_FORMAT_G12X4B12X4G12X4R12X4_4PACK16_422_UNORM VK_FORMAT_G16B16G16R16_UNORM

B

G0

R

G1

VK_FORMAT_B10X6G10X6R10X6G10X6_4PACK16_422_UNORM<= /code> VK_FORMAT_B12X4G12X4R12X4G12X4_4PACK16_422_UNORM VK_FORMAT_B16G16R16G16_422_UNORM

R

VK_FORMAT_R32_*

R

G

VK_FORMAT_R32G32_*

R

G

B

VK_FORMAT_R32G32B32_*

R

G

B

A

VK_FORMAT_R32G32B32A32_*

R

VK_FORMAT_R64_*

R

G

VK_FORMAT_R64G64_*

VK_FORMAT_R64G64B64_* as VK_FORM= AT_R64G64_* but with B in bytes 16-23

VK_FORMAT_R64G64B64A64_* as VK_F= ORMAT_R64G64B64_* but with A in bytes 24-31

Packed formats store multiple components within one underlying type. The bit representation is that the first component specified in the name of the format is in the most-significant bits and the last component specified is in the least-significant bits of the underlying type. The in-memory ordering of bytes comprising the underlying type is determine= d by the host endianness.

Table 51. Bit mappings for packed 8-bit formats
Bit

7

6

5

4

3

2

1

0

VK_FORMAT_R4G4_UNORM_PACK8

R

G

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>3

<= sub>2

<= sub>1

<= sub>0

Table 52. Bit mappings for packed 16-bit formats
Bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

VK_FORMAT_R4G4B4A4_UNORM_PACK16

R

G

B

A

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_B4G4R4A4_UNORM_PACK16

B

G

R

A

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_R5G6B5_UNORM_PACK16

R

G

B

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_B5G6R5_UNORM_PACK16

B

G

R

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_R5G5B5A1_UNORM_PACK16

R

G

B

<= strong>A

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>0

VK_FORMAT_B5G5R5A1_UNORM_PACK16

B

G

R

<= strong>A

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>0

VK_FORMAT_A1R5G5B5_UNORM_PACK16

<= strong>A

R

G

B

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_R10X6_UNORM_PACK16

R

X

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_R12X4_UNORM_PACK16

R

X

<= sub>11

<= sub>10

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>3

<= sub>2

<= sub>1

<= sub>0

Table 53. Bit mappings for packed 32-bit formats
Bit

31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

VK_FORMAT_A8B8G8R8_*_PACK32

A

B

G

R

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_A2R10G10B10_*_PACK32

A

R

G

B

<= sub>1

<= sub>0

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_A2B10G10R10_*_PACK32

A

B

G

R

<= sub>1

<= sub>0

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_B10G11R11_UFLOAT_PACK32

B

G

R

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>10

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>10

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_E5B9G9R9_UFLOAT_PACK32

E

B

G

R

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

VK_FORMAT_X8_D24_UNORM_PACK32

X

D

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

<= sub>23

<= sub>22

<= sub>21

<= sub>20

<= sub>19

<= sub>18

<= sub>17

<= sub>16

<= sub>15

<= sub>14

<= sub>13

<= sub>12

<= sub>11

<= sub>10

<= sub>9

<= sub>8

<= sub>7

<= sub>6

<= sub>5

<= sub>4

<= sub>3

<= sub>2

<= sub>1

<= sub>0

Depth/Stencil Formats

Depth/stencil formats are considered opaque and need not be stored in th= e exact number of bits per texel or component ordering indicated by the forma= t enum. However, implementations must not substit= ute a different depth or stencil precision than that described in the format (e.g. D16 must not be implemented as D24 or D32).

Format Compatibility Clas= ses

Uncompressed color formats are compatible with each other if th= ey occupy the same number of bits per data element. Compressed color formats are compatible with each other if the only difference between them is the numerical type of the uncompressed pixels (e.g. signed vs. unsigned, or SRGB vs. UNORM encoding). Each depth/stencil format is only compatible with itself. In the following table, all the formats in the same row are compatible.

Table 54. Compatible formats
Class Formats

8-b= it

VK_FORMAT_R4G4_UNORM_PACK8,
VK_FORMAT_R8_UNORM,
VK_FORMAT_R8_SNORM,
VK_FORMAT_R8_USCALED,
VK_FORMAT_R8_SSCALED,
VK_FORMAT_R8_UINT,
VK_FORMAT_R8_SINT,
VK_FORMAT_R8_SRGB

16-= bit

VK_FORMAT_R4G4B4A4_UNORM_PACK16,
VK_FORMAT_B4G4R4A4_UNORM_PACK16,
VK_FORMAT_R5G6B5_UNORM_PACK16,
VK_FORMAT_B5G6R5_UNORM_PACK16,
VK_FORMAT_R5G5B5A1_UNORM_PACK16,
VK_FORMAT_B5G5R5A1_UNORM_PACK16,
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
VK_FORMAT_R8G8_UNORM,
VK_FORMAT_R8G8_SNORM,
VK_FORMAT_R8G8_USCALED,
VK_FORMAT_R8G8_SSCALED,
VK_FORMAT_R8G8_UINT,
VK_FORMAT_R8G8_SINT,
VK_FORMAT_R8G8_SRGB,
VK_FORMAT_R16_UNORM,
VK_FORMAT_R16_SNORM,
VK_FORMAT_R16_USCALED,
VK_FORMAT_R16_SSCALED,
VK_FORMAT_R16_UINT,
VK_FORMAT_R16_SINT,
VK_FORMAT_R16_SFLOAT,
VK_FORMAT_R10X6_UNORM_PACK16,
VK_FORMAT_R12X4_UNORM_PACK16

24-= bit

VK_FORMAT_R8G8B8_UNORM,
VK_FORMAT_R8G8B8_SNORM,
VK_FORMAT_R8G8B8_USCALED,
VK_FORMAT_R8G8B8_SSCALED,
VK_FORMAT_R8G8B8_UINT,
VK_FORMAT_R8G8B8_SINT,
VK_FORMAT_R8G8B8_SRGB,
VK_FORMAT_B8G8R8_UNORM,
VK_FORMAT_B8G8R8_SNORM,
VK_FORMAT_B8G8R8_USCALED,
VK_FORMAT_B8G8R8_SSCALED,
VK_FORMAT_B8G8R8_UINT,
VK_FORMAT_B8G8R8_SINT,
VK_FORMAT_B8G8R8_SRGB

32-= bit

VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_R8G8B8A8_SNORM,
VK_FORMAT_R8G8B8A8_USCALED,
VK_FORMAT_R8G8B8A8_SSCALED,
VK_FORMAT_R8G8B8A8_UINT,
VK_FORMAT_R8G8B8A8_SINT,
VK_FORMAT_R8G8B8A8_SRGB,
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_B8G8R8A8_SNORM,
VK_FORMAT_B8G8R8A8_USCALED,
VK_FORMAT_B8G8R8A8_SSCALED,
VK_FORMAT_B8G8R8A8_UINT,
VK_FORMAT_B8G8R8A8_SINT,
VK_FORMAT_B8G8R8A8_SRGB,
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
VK_FORMAT_A8B8G8R8_SNORM_PACK32,
VK_FORMAT_A8B8G8R8_USCALED_PACK32,
VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
VK_FORMAT_A8B8G8R8_UINT_PACK32,
VK_FORMAT_A8B8G8R8_SINT_PACK32,
VK_FORMAT_A8B8G8R8_SRGB_PACK32,
VK_FORMAT_A2R10G10B10_UNORM_PACK32,
VK_FORMAT_A2R10G10B10_SNORM_PACK32,
VK_FORMAT_A2R10G10B10_USCALED_PACK32,
VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
VK_FORMAT_A2R10G10B10_UINT_PACK32,
VK_FORMAT_A2R10G10B10_SINT_PACK32,
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
VK_FORMAT_A2B10G10R10_SNORM_PACK32,
VK_FORMAT_A2B10G10R10_USCALED_PACK32,
VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
VK_FORMAT_A2B10G10R10_UINT_PACK32,
VK_FORMAT_A2B10G10R10_SINT_PACK32,
VK_FORMAT_R16G16_UNORM,
VK_FORMAT_R16G16_SNORM,
VK_FORMAT_R16G16_USCALED,
VK_FORMAT_R16G16_SSCALED,
VK_FORMAT_R16G16_UINT,
VK_FORMAT_R16G16_SINT,
VK_FORMAT_R16G16_SFLOAT,
VK_FORMAT_R32_UINT,
VK_FORMAT_R32_SINT,
VK_FORMAT_R32_SFLOAT,
VK_FORMAT_B10G11R11_UFLOAT_PACK32,
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
VK_FORMAT_R12X4G12X4_UNORM_2PACK16

32-= bit G8B8G8R8

VK_FORMAT_G8B8G8R8_422_UNORM

32-= bit B8G8R8G8

VK_FORMAT_B8G8R8G8_422_UNORM

48-= bit

VK_FORMAT_R16G16B16_UNORM,
VK_FORMAT_R16G16B16_SNORM,
VK_FORMAT_R16G16B16_USCALED,
VK_FORMAT_R16G16B16_SSCALED,
VK_FORMAT_R16G16B16_UINT,
VK_FORMAT_R16G16B16_SINT,
VK_FORMAT_R16G16B16_SFLOAT

64-= bit

VK_FORMAT_R16G16B16A16_UNORM,
VK_FORMAT_R16G16B16A16_SNORM,
VK_FORMAT_R16G16B16A16_USCALED,
VK_FORMAT_R16G16B16A16_SSCALED,
VK_FORMAT_R16G16B16A16_UINT,
VK_FORMAT_R16G16B16A16_SINT,
VK_FORMAT_R16G16B16A16_SFLOAT,
VK_FORMAT_R32G32_UINT,
VK_FORMAT_R32G32_SINT,
VK_FORMAT_R32G32_SFLOAT,
VK_FORMAT_R64_UINT,
VK_FORMAT_R64_SINT,
VK_FORMAT_R64_SFLOAT

64-= bit R10G10B10A10

VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16

64-= bit G10B10G10R10

VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16

64-= bit B10G10R10G10

VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16

64-= bit R12G12B12A12

VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16

64-= bit G12B12G12R12

VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16

64-= bit B12G12R12G12

VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16

64-= bit G16B16G16R16

VK_FORMAT_G16B16G16R16_422_UNORM

64-= bit B16G16R16G16

VK_FORMAT_B16G16R16G16_422_UNORM

96-= bit

VK_FORMAT_R32G32B32_UINT,
VK_FORMAT_R32G32B32_SINT,
VK_FORMAT_R32G32B32_SFLOAT

128= -bit

VK_FORMAT_R32G32B32A32_UINT,
VK_FORMAT_R32G32B32A32_SINT,
VK_FORMAT_R32G32B32A32_SFLOAT,
VK_FORMAT_R64G64_UINT,
VK_FORMAT_R64G64_SINT,
VK_FORMAT_R64G64_SFLOAT

192= -bit

VK_FORMAT_R64G64B64_UINT,
VK_FORMAT_R64G64B64_SINT,
VK_FORMAT_R64G64B64_SFLOAT

256= -bit

VK_FORMAT_R64G64B64A64_UINT,
VK_FORMAT_R64G64B64A64_SINT,
VK_FORMAT_R64G64B64A64_SFLOAT

BC1= _RGB

VK_FORMAT_BC1_RGB_UNORM_BLOCK,
VK_FORMAT_BC1_RGB_SRGB_BLOCK

BC1= _RGBA

VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
VK_FORMAT_BC1_RGBA_SRGB_BLOCK

BC2=

VK_FORMAT_BC2_UNORM_BLOCK,
VK_FORMAT_BC2_SRGB_BLOCK

BC3=

VK_FORMAT_BC3_UNORM_BLOCK,
VK_FORMAT_BC3_SRGB_BLOCK

BC4=

VK_FORMAT_BC4_UNORM_BLOCK,
VK_FORMAT_BC4_SNORM_BLOCK

BC5=

VK_FORMAT_BC5_UNORM_BLOCK,
VK_FORMAT_BC5_SNORM_BLOCK

BC6= H

VK_FORMAT_BC6H_UFLOAT_BLOCK,
VK_FORMAT_BC6H_SFLOAT_BLOCK

BC7=

VK_FORMAT_BC7_UNORM_BLOCK,
VK_FORMAT_BC7_SRGB_BLOCK

ETC= 2_RGB

VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK

ETC= 2_RGBA

VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK

ETC= 2_EAC_RGBA

VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK

EAC= _R

VK_FORMAT_EAC_R11_UNORM_BLOCK,
VK_FORMAT_EAC_R11_SNORM_BLOCK

EAC= _RG

VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
VK_FORMAT_EAC_R11G11_SNORM_BLOCK

AST= C_4x4

VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
VK_FORMAT_ASTC_4x4_SRGB_BLOCK

AST= C_5x4

VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
VK_FORMAT_ASTC_5x4_SRGB_BLOCK

AST= C_5x5

VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
VK_FORMAT_ASTC_5x5_SRGB_BLOCK

AST= C_6x5

VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
VK_FORMAT_ASTC_6x5_SRGB_BLOCK

AST= C_6x6

VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
VK_FORMAT_ASTC_6x6_SRGB_BLOCK

AST= C_8x5

VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
VK_FORMAT_ASTC_8x5_SRGB_BLOCK

AST= C_8x6

VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
VK_FORMAT_ASTC_8x6_SRGB_BLOCK

AST= C_8x8

VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
VK_FORMAT_ASTC_8x8_SRGB_BLOCK

AST= C_10x5

VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
VK_FORMAT_ASTC_10x5_SRGB_BLOCK

AST= C_10x6

VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
VK_FORMAT_ASTC_10x6_SRGB_BLOCK

AST= C_10x8

VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
VK_FORMAT_ASTC_10x8_SRGB_BLOCK

AST= C_10x10

VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
VK_FORMAT_ASTC_10x10_SRGB_BLOCK

AST= C_12x10

VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
VK_FORMAT_ASTC_12x10_SRGB_BLOCK

AST= C_12x12

VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
VK_FORMAT_ASTC_12x12_SRGB_BLOCK

D16=

VK_FORMAT_D16_UNORM

D24=

VK_FORMAT_X8_D24_UNORM_PACK32

D32=

VK_FORMAT_D32_SFLOAT

S8<= /p>

VK_FORMAT_S8_UINT

D16= S8

VK_FORMAT_D16_UNORM_S8_UINT

D24= S8

VK_FORMAT_D24_UNORM_S8_UINT

D32= S8

VK_FORMAT_D32_SFLOAT_S8_UINT

8-b= it 3-plane 420

VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM

8-b= it 2-plane 420

VK_FORMAT_G8_B8R8_2PLANE_420_UNORM

8-b= it 3-plane 422

VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM

8-b= it 2-plane 422

VK_FORMAT_G8_B8R8_2PLANE_422_UNORM

8-b= it 3-plane 444

VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM

10-= bit 3-plane 420

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16

10-= bit 2-plane 420

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16

10-= bit 3-plane 422

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16

10-= bit 2-plane 422

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16

10-= bit 3-plane 444

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16

12-= bit 3-plane 420

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16

12-= bit 2-plane 420

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16

12-= bit 3-plane 422

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16

12-= bit 2-plane 422

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16

12-= bit 3-plane 444

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16

16-= bit 3-plane 420

VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM

16-= bit 2-plane 420

VK_FORMAT_G16_B16R16_2PLANE_420_UNORM

16-= bit 3-plane 422

VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM

16-= bit 2-plane 422

VK_FORMAT_G16_B16R16_2PLANE_422_UNORM

16-= bit 3-plane 444

VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM

32.4.2. Format Properties

To query supported format features which are properties of the physical device, call:

void vkGetPhysicalDeviceFormatProperties(
    VkPhysicalDevice                            physicalDevice,
    VkFormat                                    format,
    VkFormatProperties*                         pFormatProperties);<=
/pre>
  • physicalDevice is the physical device from which to query t= he format properties.

  • format is the format whose properties are queried.

  • pFormatProperties is a pointer to a VkF= ormatProperties structure in which physical device properties for format are returned.

Valid Usage (Implicit)
  • physicalDevice must= be a valid VkPhysicalDevice handle

  • = format must be a valid VkFormat value

  • pFormatProperties must be a valid pointer to a VkFormatProperties structure

The VkFormatProperties structure is defined as:

typedef struct VkFormatProperti=
es {
    VkFormatFeatureFlags    linearTilingFeatures;
    VkFormatFeatureFlags    optimalTilingFeatures;
    VkFormatFeatureFlags    bufferFeatures;
} VkFormatProperties;
  • linearTilingFeatures is a bitmask of VkFormatFeatureFlagBits specifying features supported by images created with a tiling parameter of VK_IMAGE_TILING_LINEAR.

  • optimalTilingFeatures is a bitmask of VkFormatFeatureFlagBits specifying features su= pported by images created with a tiling parameter of VK_IMAGE_TILING_OPTIM= AL.

  • bufferFeatures is a bitmask of VkF= ormatFeatureFlagBits specifying features supported by buffers.

Note

If no format feature flags are supported, the format itself is not supported, and images of that format cannot be created.

If format is a block-compression format, then bufferF= eatures must not support any features for the for= mat.

If format is a multi-plane format then linearTilingFe= atures and optimalTilingFeatures must n= ot contain VK_FORMAT_FEATURE_DISJOINT_BIT.

Bits which can be set in the VkFormatProperties features linearTilingFeatures, optimalTilingFeatures, and bufferFeatures are:

typedef enum VkFormatFeatureFla=
gBits {
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT =3D 0x00000001<=
/span>,
    VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT =3D 0x00000002<=
/span>,
    VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT =3D 0x00=
000004,
    VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT =3D 0x00=
000008,
    VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT =3D 0x00=
000010,
    VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT =3D 0x00000020,
    VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT =3D 0x00000040<=
/span>,
    VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT =3D 0x000000=
80,
    VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT =3D 0x=
00000100,
    VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT =3D =
0x00000200,
    VK_FORMAT_FEATURE_BLIT_SRC_BIT =3D 0x00000400,
    VK_FORMAT_FEATURE_BLIT_DST_BIT =3D 0x00000800,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT =3D 0x00001000,
    VK_FORMAT_FEATURE_TRANSFER_SRC_BIT =3D 0x00004000,
    VK_FORMAT_FEATURE_TRANSFER_DST_BIT =3D 0x00008000,
    VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT =3D 0=
x00020000,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT =3D =
0x00040000,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTIO=
N_FILTER_BIT =3D 0x00080000,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_=
EXPLICIT_BIT =3D 0x00100000,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_=
EXPLICIT_FORCEABLE_BIT =3D 0x00200000,
    VK_FORMAT_FEATURE_DISJOINT_BIT =3D 0x00400000,
    VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT =3D 0x=
00800000,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG =3D 0x00002000,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT =3D 0x00010000,
    VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR =3D VK_FORMAT_FEATURE_TRANSFER_S=
RC_BIT,
    VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR =3D VK_FORMAT_FEATURE_TRANSFER_D=
ST_BIT,
    VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR =3D VK_FORMAT_FEATURE=
_MIDPOINT_CHROMA_SAMPLES_BIT,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR =
=3D VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTIO=
N_FILTER_BIT_KHR =3D VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPAR=
ATE_RECONSTRUCTION_FILTER_BIT,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_=
EXPLICIT_BIT_KHR =3D VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROM=
A_RECONSTRUCTION_EXPLICIT_BIT,
    VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_=
EXPLICIT_FORCEABLE_BIT_KHR =3D VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVER=
SION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT,
    VK_FORMAT_FEATURE_DISJOINT_BIT_KHR =3D VK_FORMAT_FEATURE_DISJOINT_BIT,
    VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR =3D VK_FORMAT_FEATURE_=
COSITED_CHROMA_SAMPLES_BIT,
} VkFormatFeatureFlagBits;

The following bits may be set in linearTilingFeatures and optimalTilingFeatures, specifying that the features are suppor= ted by images or image views created with the querie= d vkGetPhysicalDeviceFormatProperties::format:

  • VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT specifies that an image= view can be sampl= ed from.

  • VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT specifies that an image= view can be used as a storage images.

  • VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT specifies that a= n image view can be used as storage image that su= pports atomic operations.

  • VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT specifies that an im= age view can be used as a framebuffer color a= ttachment and as an input attachment.

  • VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT specifies that= an image view can be used as a framebuffer c= olor attachment that supports blending and as an input attachment.

  • VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT specifies th= at an image view can be used as a framebuffer d= epth/stencil attachment and as an input attachment.

  • VK_FORMAT_FEATURE_BLIT_SRC_BIT specifies that an image can be used as srcImage for the vkCmdBlitImage command.<= /p>

  • VK_FORMAT_FEATURE_BLIT_DST_BIT specifies that an image can be used as dstImage for the vkCmdBlitImage command.<= /p>

  • VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT specifies= that if VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT is also set, an image v= iew can be used with a sampler that has eithe= r of magFilter or minFilter set to VK_FILTER_LINEAR, or mipma= pMode set to VK_SAMPLER_MIPMAP_MODE_LINEAR. If VK_FORMAT_FEATURE_BLIT_SRC_BIT is also set, an image can be used as the srcImage to vkCmdBlitImage wit= h a filter of VK_FILTER_LINEAR. This bit must only be exposed for formats= that also support the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT or VK_FORMAT_FEATURE_BLIT_SRC_BIT.

    If the format being queried is a depth/stencil format, this bit only specifies that the depth aspect (not the stencil aspect) of an image of thi= s format supports linear filtering, and that linear filtering of the depth aspect is supported whether depth compare is enabled in the sampler or not. If this bit is not present, linear filtering with depth compare disabled is unsupported and linear filtering with depth compare enabled is supported, but may compute the filtered value in an = implementation-dependent manner which differs from the normal rules of linear filtering. The resulting value must be in the range = [0,1] and should be proportional to, or a weighted average of, the number of comparison passes or failures.

  • VK_FORMAT_FEATURE_TRANSFER_SRC_BIT specifies that an image = can be used as a source image for copy commands.

  • VK_FORMAT_FEATURE_TRANSFER_DST_BIT specifies that an image = can be used as a destination image for copy commands and clear= commands.

  • VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT speci= fies VkImage can be used as a sam= pled image with a min or max VkSamplerReductionModeEXT. This bit must only be exposed for formats= that also support the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT.

  • VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG specif= ies that VkImage can be used wit= h a sampler that has either of magFilter or minFilter set to VK_FILTER_CUB= IC_IMG, or be the source image for a blit with filter set to VK_FILTER_CUBIC_IMG. This bit must only be exposed for formats= that also support the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT. If the format being queried is a depth/stencil format, this only specifies that the depth aspect is cubic filterable.

  • VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT specifies tha= t an application can define a sampler Y=E2=80=99CBCR conversion using this format as a source, and that an image of this format can be used with a VkSampler= YcbcrConversionCreateInfo xChromaOffset and/or yChromaOffset of VK_CHROMA_LOCATION_MIDPOINT. Otherwise both xChromaOffset and yChromaOffset must be VK_CHROMA_LOCATION_COSITED_EVEN. If a format does not incorporate chroma downsampling (it is not a =E2=80=9C422=E2=80=9D or =E2=80=9C420=E2=80=9D format) but the implementati= on supports sampler Y=E2=80=99CBCR conversion for this format, the implem= entation must set VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT.

  • VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT specifies that= an application can define a sampler Y=E2=80=99CBCR conversion using this format as a source, and that an image of this format can be used with a VkSampler= YcbcrConversionCreateInfo xChromaOffset and/or yChromaOffset of VK_CHROMA_LOCATION_COSITED_EVEN. Otherwise both xChromaOffset and yChromaOffset must be VK_CHROMA_LOCATION_MIDPOINT. If neither VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT nor VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT is set, the application must not define a sampler Y=E2=80=99CBCR conversion using this format as a = source.

  • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT= specifies that the format can do linear sampler filtering (min/magFilter) whilst sampler Y=E2=80=99CBCR convers= ion is enabled.

  • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTR= UCTION_FILTER_BIT specifies that the format can have different chroma, min, and mag filters.

  • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUC= TION_EXPLICIT_BIT specifies that reconstruction is explicit, as described in Chroma Reconstruction. If this bit is not present, reconstruction is implicit by default.

  • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUC= TION_EXPLICIT_FORCEABLE_BIT specifies that reconstruction can be forc= ibly made explicit by setting VkSamplerYcbcrConversionCreateInfo:= :forceExplicitReconstruction to VK_TRUE.

  • VK_FORMAT_FEATURE_DISJOINT_BIT specifies that a multi-plana= r image can have the VK_IMAGE_CREATE_DISJOI= NT_BIT set during image creation. An implementation must not set VK_F= ORMAT_FEATURE_DISJOINT_BIT for single-plane formats.

The following bits may be set in bufferFeatures, specifying that the features are supported by buffers or buffer views created with the queried vkGetPhysicalDeviceProperties::for= mat:

  • VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT specifies that t= he format can be used to create a buffer vie= w that can be bound to a VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER descriptor.

  • VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT specifies that t= he format can be used to create a buffer vie= w that can be bound to a VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER descriptor.

  • VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT specifies= that atomic operations are supported on VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER with this format.

  • VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT specifies that the form= at can be used as a vertex attribute format (VkVertexInputAttributeDescription::format).

typedef VkFlags VkFormatFeatureFlags;

VkFormatFeatureFlags is a bitmask type for setting a mask o= f zero or more VkFormatFeatureFlagBits.

To query supported format features which are properties of the physical device, call:

void vkGetPhysicalDeviceFormatProperties2(
    VkPhysicalDevice                            physicalDevice,
    VkFormat                                    format,
    VkFormatProperties2*                        pFormatProperties);<=
/pre>

or the equivalent command

void vkGetPhysicalDeviceFormatProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    VkFormat                                    format,
    VkFormatProperties2*                        pFormatProperties);<=
/pre>
  • physicalDevice is the physical device from which to query t= he format properties.

  • format is the format whose properties are queried.

  • pFormatProperties is a pointer to a Vk= FormatProperties2 structure in which physical device properties for format are returned.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • format must be a valid VkFormat value

  • pFormatProperties must be a valid pointer to a VkFormatProperties2 structure<= /p>

The VkFormatProperties2 structure is defined as:

typedef struct VkFormatProperti=
es2 {
    VkStructureType       sType;
    void*                 pNext;
    VkFormatProperties    formatProperties;
} VkFormatProperties2;

or the equivalent

typedef VkFormatProperties2 VkFormatProperties2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • formatProperties is a structure of type VkFormatProperties describing features supported by the requested format.

Valid Usage (Implicit)
  • sType <= strong class=3D"purple">must be VK_STRUCTURE_TYPE_FORMAT_PRO= PERTIES_2

  • pNext <= strong class=3D"purple">must be NULL

32.4.3. Required Format Support=

Implementations must support at least = the following set of features on the listed formats. For images, these features must be suppor= ted for every VkImageType (including arrayed and cube variants) unless otherwise noted. These features are supported on existing formats without needing to advertise an extension or needing to explicitly enable them. Support for additional functionality beyond the requirements listed here is queried using the vkGetPhysicalDeviceF= ormatProperties command.

Note

The required formats are supported for all VkImageCr= eateFlags values as long as those flag values are otherwise allowed.

The following tables show which feature bits mu= st be supported for each format. Formats that are required to support VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT m= ust also support VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT.

Table 55. Key for format feature tables

= =E2=9C=93

Thi= s feature must be supported on the named = format

= =E2=80=A0

Thi= s feature must be supported on at least s= ome of the named formats, with more information in the table where the symbol appears

Table 56. Feature bits in optimalTilingFeatu= res

VK_FORMAT_FEATURE_TRANSFER_SRC_BIT

VK_FORMAT_FEATURE_TRANSFER_DST_BIT

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

VK_FORMAT_FEATURE_BLIT_SRC_BIT

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

VK_FORMAT_FEATURE_BLIT_DST_BIT

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT

Table 57. Feature bits in bufferFeatures

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT

Table 58. Mandatory format support: sub-byte chann= els

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_UNDEFINED

VK_FORMAT_R4G4_UNORM_PACK8

VK_FORMAT_R4G4B4A4_UNORM_PACK16

VK_FORMAT_B4G4R4A4_UNORM_PACK16

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R5G6B5_UNORM_PACK16

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_B5G6R5_UNORM_PACK16

VK_FORMAT_R5G5B5A1_UNORM_PACK16

VK_FORMAT_B5G5R5A1_UNORM_PACK16

VK_FORMAT_A1R5G5B5_UNORM_PACK16

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

Table 59. Mandatory format support: 1-3 byte-sized= channels

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_R8_UNORM

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8_SNORM

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8_USCALED

VK_FORMAT_R8_SSCALED

VK_FORMAT_R8_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8_SRGB

VK_FORMAT_R8G8_UNORM

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8G8_SNORM

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8G8_USCALED

VK_FORMAT_R8G8_SSCALED

VK_FORMAT_R8G8_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8G8_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8G8_SRGB

VK_FORMAT_R8G8B8_UNORM

VK_FORMAT_R8G8B8_SNORM

VK_FORMAT_R8G8B8_USCALED

VK_FORMAT_R8G8B8_SSCALED

VK_FORMAT_R8G8B8_UINT

VK_FORMAT_R8G8B8_SINT

VK_FORMAT_R8G8B8_SRGB

VK_FORMAT_B8G8R8_UNORM

VK_FORMAT_B8G8R8_SNORM

VK_FORMAT_B8G8R8_USCALED

VK_FORMAT_B8G8R8_SSCALED

VK_FORMAT_B8G8R8_UINT

VK_FORMAT_B8G8R8_SINT

VK_FORMAT_B8G8R8_SRGB

Table 60. Mandatory format support: 4 byte-sized c= hannels

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_R8G8B8A8_UNORM

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8G8B8A8_SNORM

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8G8B8A8_USCALED

VK_FORMAT_R8G8B8A8_SSCALED

VK_FORMAT_R8G8B8A8_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8G8B8A8_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R8G8B8A8_SRGB

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_B8G8R8A8_UNORM

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_B8G8R8A8_SNORM

VK_FORMAT_B8G8R8A8_USCALED

VK_FORMAT_B8G8R8A8_SSCALED

VK_FORMAT_B8G8R8A8_UINT

VK_FORMAT_B8G8R8A8_SINT

VK_FORMAT_B8G8R8A8_SRGB

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_A8B8G8R8_UNORM_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_A8B8G8R8_SNORM_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_A8B8G8R8_USCALED_PACK32

VK_FORMAT_A8B8G8R8_SSCALED_PACK32

VK_FORMAT_A8B8G8R8_UINT_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_A8B8G8R8_SINT_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_A8B8G8R8_SRGB_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

Table 61. Mandatory format support: 10-bit channel= s

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_A2R10G10B10_UNORM_PACK32

VK_FORMAT_A2R10G10B10_SNORM_PACK32

VK_FORMAT_A2R10G10B10_USCALED_PACK32

VK_FORMAT_A2R10G10B10_SSCALED_PACK32

VK_FORMAT_A2R10G10B10_UINT_PACK32

VK_FORMAT_A2R10G10B10_SINT_PACK32

VK_FORMAT_A2B10G10R10_UNORM_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_A2B10G10R10_SNORM_PACK32

VK_FORMAT_A2B10G10R10_USCALED_PACK32

VK_FORMAT_A2B10G10R10_SSCALED_PACK32

VK_FORMAT_A2B10G10R10_UINT_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_A2B10G10R10_SINT_PACK32

Table 62. Mandatory format support: 16-bit channel= s

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_R16_UNORM

= =E2=9C=93

VK_FORMAT_R16_SNORM

= =E2=9C=93

VK_FORMAT_R16_USCALED

VK_FORMAT_R16_SSCALED

VK_FORMAT_R16_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R16_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R16_SFLOAT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R16G16_UNORM

= =E2=9C=93

VK_FORMAT_R16G16_SNORM

= =E2=9C=93

VK_FORMAT_R16G16_USCALED

VK_FORMAT_R16G16_SSCALED

VK_FORMAT_R16G16_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R16G16_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R16G16_SFLOAT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R16G16B16_UNORM

VK_FORMAT_R16G16B16_SNORM

VK_FORMAT_R16G16B16_USCALED

VK_FORMAT_R16G16B16_SSCALED

VK_FORMAT_R16G16B16_UINT

VK_FORMAT_R16G16B16_SINT

VK_FORMAT_R16G16B16_SFLOAT

VK_FORMAT_R16G16B16A16_UNORM

= =E2=9C=93

VK_FORMAT_R16G16B16A16_SNORM

= =E2=9C=93

VK_FORMAT_R16G16B16A16_USCALED

VK_FORMAT_R16G16B16A16_SSCALED

VK_FORMAT_R16G16B16A16_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R16G16B16A16_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R16G16B16A16_SFLOAT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

Table 63. Mandatory format support: 32-bit channel= s

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_R32_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R32_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R32_SFLOAT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R32G32_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R32G32_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R32G32_SFLOAT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R32G32B32_UINT

= =E2=9C=93

VK_FORMAT_R32G32B32_SINT

= =E2=9C=93

VK_FORMAT_R32G32B32_SFLOAT

= =E2=9C=93

VK_FORMAT_R32G32B32A32_UINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R32G32B32A32_SINT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_R32G32B32A32_SFLOAT

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

Table 64. Mandatory format support: 64-bit/uneven = channels

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_R64_UINT

VK_FORMAT_R64_SINT

VK_FORMAT_R64_SFLOAT

VK_FORMAT_R64G64_UINT

VK_FORMAT_R64G64_SINT

VK_FORMAT_R64G64_SFLOAT

VK_FORMAT_R64G64B64_UINT

VK_FORMAT_R64G64B64_SINT

VK_FORMAT_R64G64B64_SFLOAT

VK_FORMAT_R64G64B64A64_UINT

VK_FORMAT_R64G64B64A64_SINT

VK_FORMAT_R64G64B64A64_SFLOAT

VK_FORMAT_B10G11R11_UFLOAT_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_E5B9G9R9_UFLOAT_PACK32

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

Table 65. Mandatory format support: depth/stencil = with VkImageType VK_IMAGE_TYPE_2D

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_D16_UNORM

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_X8_D24_UNORM_PACK32

= =E2=80=A0

VK_FORMAT_D32_SFLOAT

= =E2=9C=93

= =E2=9C=93

= =E2=80=A0

VK_FORMAT_S8_UINT

VK_FORMAT_D16_UNORM_S8_UINT

VK_FORMAT_D24_UNORM_S8_UINT

= =E2=80=A0

VK_FORMAT_D32_SFLOAT_S8_UINT

= =E2=80=A0

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT fea= ture must be supported for at least one of VK_FORMAT_X8_D24_UNORM_PACK32 an= d VK_FORMAT_D32_SFLOAT, and must be supported for at least one of VK_FORMAT_D24_UNORM_S8_UINT and VK_FORMAT_D32_SFLOAT_S8_= UINT.

Table 66. Mandatory format support: BC compressed = formats with VkImageType VK_IMAGE_TYPE_2D and= VK_IMAGE_TYPE_3D

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_BC1_RGB_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC1_RGB_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC1_RGBA_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC1_RGBA_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC2_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC2_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC3_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC3_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC4_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC4_SNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC5_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC5_SNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC6H_UFLOAT_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC6H_SFLOAT_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC7_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_BC7_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

The VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_BLIT_SRC_BIT and VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT features must be supported in optimalTilingFeatures for all the formats in at l= east one of: this table, Mandatory form= at support: ETC2 and EAC compressed formats with VkImageTy= pe VK_IMAGE_TYPE_2D, or Mandatory format support: ASTC LD= R compressed formats with VkImageType VK_IMAGE_T= YPE_2D.

Table 67. Mandatory format support: ETC2 and EAC c= ompressed formats with VkImageType VK_IMAGE_TYPE_2D<= /code>

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_EAC_R11_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_EAC_R11_SNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_EAC_R11G11_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_EAC_R11G11_SNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

The VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_BLIT_SRC_BIT and VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT features must be supported in optimalTilingFeatures for all the formats in at l= east one of: this table, Mandatory form= at support: BC compressed formats with VkImageType VK_IMAGE_TYPE_2D and VK_IMAGE_TYPE_3D, or Mandatory format support: ASTC LD= R compressed formats with VkImageType VK_IMAGE_T= YPE_2D.

Table 68. Mandatory format support: ASTC LDR compr= essed formats with VkImageType VK_IMAGE_TYPE_2D

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT=

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT

=E2=86=93

VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT

=

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT

=E2=86=93

VK_FORMAT_FEATURE_BLIT_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT

=E2=86=93

VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT<= /p>

=E2=86=93

VK_FORMAT_FEATURE_BLIT_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

Format

VK_FORMAT_ASTC_4x4_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_4x4_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_5x4_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_5x4_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_5x5_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_5x5_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_6x5_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_6x5_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_6x6_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_6x6_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_8x5_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_8x5_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_8x6_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_8x6_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_8x8_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_8x8_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_10x5_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_10x5_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_10x6_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_10x6_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_10x8_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_10x8_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_10x10_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_10x10_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_12x10_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_12x10_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_12x12_UNORM_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

VK_FORMAT_ASTC_12x12_SRGB_BLOCK

= =E2=80=A0

= =E2=80=A0

= =E2=80=A0

The VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_BLIT_SRC_BIT and VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT features must be supported in optimalTilingFeatures for all the formats in at l= east one of: this table, Mandatory form= at support: BC compressed formats with VkImageType VK_IMAGE_TYPE_2D and VK_IMAGE_TYPE_3D, or Mandatory format support: ETC2 and= EAC compressed formats with VkImageType VK_IMAG= E_TYPE_2D.

VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG must be supported for the following formats:

  • VK_FORMAT_R4G4_UNORM_PACK8

  • VK_FORMAT_R4G4B4A4_UNORM_PACK16

  • VK_FORMAT_B4G4R4A4_UNORM_PACK16

  • VK_FORMAT_R5G6B5_UNORM_PACK16

  • VK_FORMAT_B5G6R5_UNORM_PACK16

  • VK_FORMAT_R5G5B5A1_UNORM_PACK16

  • VK_FORMAT_B5G5R5A1_UNORM_PACK16

  • VK_FORMAT_A1R5G5B5_UNORM_PACK16

  • VK_FORMAT_R8_UNORM

  • VK_FORMAT_R8_SNORM

  • VK_FORMAT_R8_SRGB

  • VK_FORMAT_R8G8_UNORM

  • VK_FORMAT_R8G8_SNORM

  • VK_FORMAT_R8G8_SRGB

  • VK_FORMAT_R8G8B8_UNORM

  • VK_FORMAT_R8G8B8_SNORM

  • VK_FORMAT_R8G8B8_SRGB

  • VK_FORMAT_B8G8R8_UNORM

  • VK_FORMAT_B8G8R8_SNORM

  • VK_FORMAT_B8G8R8_SRGB

  • VK_FORMAT_R8G8B8A8_UNORM

  • VK_FORMAT_R8G8B8A8_SNORM

  • VK_FORMAT_R8G8B8A8_SRGB

  • VK_FORMAT_B8G8R8A8_UNORM

  • VK_FORMAT_B8G8R8A8_SNORM

  • VK_FORMAT_B8G8R8A8_SRGB

  • VK_FORMAT_A8B8G8R8_UNORM_PACK32

  • VK_FORMAT_A8B8G8R8_SNORM_PACK32

  • VK_FORMAT_A8B8G8R8_USCALED_PACK32

  • VK_FORMAT_A8B8G8R8_SSCALED_PACK32

  • VK_FORMAT_A8B8G8R8_UINT_PACK32

  • VK_FORMAT_A8B8G8R8_SINT_PACK32

  • VK_FORMAT_A8B8G8R8_SRGB_PACK32

If ETC2 compressed formats are supported, the following additional forma= ts must support VK_FORMAT_FEATURE_SAMP= LED_IMAGE_FILTER_CUBIC_BIT_IMG:

  • VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK

  • VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK

  • VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK

  • VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK

  • VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK

  • VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK

To be used with VkImageView with subresourceRange.asp= ectMask =3D VK_IMAGE_ASPECT_COLOR_BIT, sampler Y=E2=80=99CBCR conversion must be enabled for the following formats:

Table 69. Formats requiring sampler Y=E2=80=99CBCR conversion for VK_IMAGE_ASPECT_COLOR_BIT image views

VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_= RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_= RECONSTRUCTION_EXPLICIT_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE= _RECONSTRUCTION_FILTER_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_F= ILTER_BIT

=E2=86=93

VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT

<= /td>

=E2=86=93

VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT

=E2=86=93

VK_FORMAT_FEATURE_TRANSFER_DST_BIT

=E2=86=93

VK_FORMAT_FEATURE_TRANSFER_SRC_BIT

=E2=86=93

VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT

=E2=86=93

VK_FORMAT_FEATURE_DISJOINT_BIT

=E2=86=93

Format

<= strong>Planes

VK_FORMAT_G8B8G8R8_422_UNORM

1=

VK_FORMAT_B8G8R8G8_422_UNORM

1=

VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM

3=

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_G8_B8R8_2PLANE_420_UNORM

2=

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

= =E2=9C=93

VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM

3=

VK_FORMAT_G8_B8R8_2PLANE_422_UNORM

2=

VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM

3=

VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16

1=

VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16

1=

VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16

1=

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16

3=

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16

2=

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16

3=

VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16

2=

VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16

3=

VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16

1=

VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16

1=

VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16

1=

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16

3=

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16

2=

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16

3=

VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16

2=

VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16

3=

VK_FORMAT_G16B16G16R16_422_UNORM

1=

VK_FORMAT_B16G16R16G16_422_UNORM

1=

VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM

3=

VK_FORMAT_G16_B16R16_2PLANE_420_UNORM

2=

VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM

3=

VK_FORMAT_G16_B16R16_2PLANE_422_UNORM

2=

VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM

3=

Format features marked =E2=9C=93 must<= /strong> be supported only if VkPhysicalDeviceSamplerYcbcrConversionFeatures is enabled

32.5. Additional Image Capabiliti= es

In addition to the minimum capabilities described in the previous sectio= ns (Limits and Formats), implementations may support additional ca= pabilities for certain types of images. For example, larger dimensions or additional sample counts for certain imag= e types, or additional capabilities for linear tiling format images.=

To query additional capabilities specific to image types, call:

VkResult vkGetPhys=
icalDeviceImageFormatProperties(
    VkPhysicalDevice                            physicalDevice,
    VkFormat                                    format,
    VkImageType                                 type,
    VkImageTiling                               tiling,
    VkImageUsageFlags                           usage,
    VkImageCreateFlags                          flags,
    VkImageFormatProperties*                    pImageFormatProperties);

The format, type, tiling, u= sage, and flags parameters correspond to parameters that would be consumed by vkCreateImage (as members of VkImageCreateInfo).

If format is not a supported image format, or if the combin= ation of format, type, tiling, usage, and flags is not supported for images, then vkGetPhysicalDeviceImageFormatProperties returns VK_ERROR_FORMAT_NOT_SUPPORTED.

The limitations on an image format that are reported by vkGetPhysicalDeviceImageFormatProperties have the following pr= operty: if usage1 and usage2 of type V= kImageUsageFlags are such that the bits set in usage1 are a subset of the bits set in u= sage2, and flags1 and flags2 of type VkI= mageCreateFlags are such that the bits set in flags1 are a subset of the bits set in f= lags2, then the limitations for usage1 and flags1 must be no more strict than the limitations for usage2 and flags2, for a= ll values of format, type, and tiling.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_FORMAT_NOT_SUPPORTED

The VkImageFormatProperties structure is defined as:

typedef struct VkImageFormatPro=
perties {
    VkExtent3D            maxExtent;
    uint32_t              maxMipLevels;
    uint32_t              maxArrayLayers;
    VkSampleCountFlags    sampleCounts;
    VkDeviceSize          maxResourceSize;
} VkImageFormatProperties;
  • maxExtent are the maximum image dimensions. See the Allowed Extent Values section below for how these values are constrained by type.

  • maxMipLevels is the maximum number of mipmap levels. maxMipLevels must be equal t= o =E2=8C=88log2(max(width, height, depth))=E2=8C=89 + 1, where width, height, and depth are taken from the corresponding members of maxExtent, except when one of the following conditions is true, in which case it may= instead be 1:

  • maxArrayLayers is the maximum number of array layers. maxArrayLayers must either b= e equal to 1 or be greater than or equal to the maxImageArrayLayers member of VkPhysicalDeviceLimits. A value of 1 is valid only if tiling is VK_IMAGE_TILING_LINEAR or if type is VK_IMA= GE_TYPE_3D.

  • sampleCounts is a bitmask of VkSampl= eCountFlagBits specifying all the supported sample counts for this image as described below.

  • maxResourceSize is an upper bound on the total image size i= n bytes, inclusive of all image subresources. Implementations may have an address space= limit on total size of a resource, which is advertised by this property. maxResourceSize must be at l= east 231.

Note

There is no mechanism to query the size of an image before creating it, = to compare that size against maxResourceSize. If an application attempts to create an image that exceeds this limit, the creation will fail and vkCreateImage will return VK_ERROR_OUT_OF_DEVICE_MEMORY. While the advertised limit must be at lea= st 231, it may not be possible to create an image that approaches that size, particularly for VK_IMAGE_TYPE_1D.

If the combination of parameters to vkGetPhysicalDeviceImageFormatProperties is not supported by t= he implementation for use in vkCreateImage, then all member= s of VkImageFormatProperties will be filled with zero.

Note

Filling VkImageFormatProperties with zero for unsupported f= ormats is an exception to the usual rule that output structures have undefined contents on error. This exception was unintentional, but is preserved for backwards compatibility.

To determine the image capabilities compatible with an external memory handle type, call:

VkResult vkGetPhys=
icalDeviceExternalImageFormatPropertiesNV(
    VkPhysicalDevice                            physicalDevice,
    VkFormat                                    format,
    VkImageType                                 type,
    VkImageTiling                               tiling,
    VkImageUsageFlags                           usage,
    VkImageCreateFlags                          flags,
    VkExternalMemoryHandleTypeFlagsNV           externalHandleType,
    VkExternalImageFormatPropertiesNV*          pExternalImageFormatPropert=
ies);

If externalHandleType is 0, pExternalImageFormatProperties::imageFormatProperties will ret= urn the same values as a call to vkGetPhy= sicalDeviceImageFormatProperties, and the other members of pExternalImageFormatProperties will all b= e 0. Otherwise, they are filled in as described for VkExternalImageFormatPropertiesNV.

Valid Usage (Implicit)
Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_FORMAT_NOT_SUPPORTED

The VkExternalImageFormatPropertiesNV structure is defined = as:

typedef struct VkExternalImageF=
ormatPropertiesNV {
    VkImageFormatProperties              imageFormatProperties;
    VkExternalMemoryFeatureFlagsNV       externalMemoryFeatures;
    VkExternalMemoryHandleTypeFlagsNV    exportFromImportedHandleTypes;
    VkExternalMemoryHandleTypeFlagsNV    compatibleHandleTypes;
} VkExternalImageFormatPropertiesNV;

Bits which can be set in VkExternalMemoryFeatureFlagBitsNV::<= code>externalMemoryFeatures, indicating properties of the external memory handle type, are:

typedef enum VkExternalMemoryFe=
atureFlagBitsNV {
    VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV =3D 0x00000001,
    VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV =3D 0x=
00000002,
    VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV =3D 0x=
00000004,
} VkExternalMemoryFeatureFlagBitsNV;
  • VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV specifies = that external memory of the specified type must be created as a dedicated allocation when used in the manner specified.

  • VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV specifies that= the implementation supports exporting handles of the specified type.

  • VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV specifies that= the implementation supports importing handles of the specified type.

typedef VkFlags VkExternalMemoryFeatureFlagsNV;

VkExternalMemoryFeatureFlagsNV is a bitmask type for settin= g a mask of zero or more VkExternalMemoryFeatureFlag= BitsNV.

To query additional capabilities specific to image types, call:

VkResult vkGetPhys=
icalDeviceImageFormatProperties2(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceImageFormatInfo2=
*     pImageFormatInfo,
    VkImageFormatProperties2*                   pImageFormatProperties);

or the equivalent command

VkResult vkGetPhys=
icalDeviceImageFormatProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceImageFormatInfo2=
*     pImageFormatInfo,
    VkImageFormatProperties2*                   pImageFormatProperties);
  • physicalDevice is the physical device from which to query t= he image capabilities.

  • pImageFormatInfo points to an instance of the VkPhysicalDeviceImageFormatInfo2 stru= cture, describing the parameters that would be consumed by vkCreateImage.

  • pImageFormatProperties points to an instance of the VkImageFormatProperties2 structure in which c= apabilities are returned.

vkGetPhysicalDeviceImageFormatProperties2 behaves similarly= to vkGetPhysicalDeviceImageFormatPro= perties, with the ability to return extended information in a pNext chain of output structures.

Valid Usage
Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pImageFormatInfo mus= t be a valid pointer to a valid VkPhysicalDeviceImageFormatI= nfo2 structure

  • pImageFormatProperties must be a valid pointer to a VkImageFormatPropertie= s2 structure

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_FORMAT_NOT_SUPPORTED

The VkPhysicalDeviceImageFormatInfo2 structure is defined a= s:

typedef struct VkPhysicalDevice=
ImageFormatInfo2 {
    VkStructureType       sType;
    const void*           pNext;
    VkFormat              format;
    VkImageType           type;
    VkImageTiling         tiling;
    VkImageUsageFlags     usage;
    VkImageCreateFlags    flags;
} VkPhysicalDeviceImageFormatInfo2;

or the equivalent

typedef VkPhysicalDeviceImageFormatInfo2 VkPhysicalDeviceImage=
FormatInfo2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure. The pNext chain of VkPhysicalDeviceImageFormatInfo2 is used to provide additional image parameters to vkGetPhysicalDeviceImageFormatProperties2.

  • format is a VkFormat value indicating the ima= ge format, corresponding to VkImageCreateInfo::format.

  • type is a VkImageType value indicating the= image type, corresponding to VkImageCreateInfo::imageType<= /code>.

  • tiling is a VkImageTiling value indicati= ng the image tiling, corresponding to VkImageCreateInfo::tiling.

  • usage is a bitmask of VkImageUsageFla= gBits indicating the intended usage of the image, corresponding to VkImageCreateInfo::usage.

  • flags is a bitmask of VkImageCreateF= lagBits indicating additional parameters of the image, corresponding to VkImageCreateInfo::flags.

The members of VkPhysicalDeviceImageFormatInfo2 correspond = to the arguments to vkGetPhysicalDeviceI= mageFormatProperties, with sType and pNext added for extensibility.

Valid Usage (Implicit)

The VkImageFormatProperties2 structure is defined as:

typedef struct VkImageFormatPro=
perties2 {
    VkStructureType            sType;
    void*                      pNext;
    VkImageFormatProperties    imageFormatProperties;
} VkImageFormatProperties2;

or the equivalent

typedef VkImageFormatProperties2 VkImageFormatProperties2KHR;<=
/code>
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure. The pNext chain of VkImageFormatProperties2 is us= ed to allow the specification of additional capabilities to be returned from vkGetPhysicalDeviceImageFormatProperties2.

  • imageFormatProperties is an instance of a VkImageFormatProperties structure in which cap= abilities are returned.

If the combination of parameters to vkGetPhysicalDeviceImageFormatProperties2 is not supported by = the implementation for use in vkCreateImage, then all member= s of imageFormatProperties will be filled with zero.

Note

Filling imageFormatProperties with zero for unsupported for= mats is an exception to the usual rule that output structures have undefined contents on error. This exception was unintentional, but is preserved for backwards compatibility. This exeption only applies to imageFormatProperties, not sType, pNext, or any structures chained from pNext.

Valid Usage (Implicit)

To determine if texture gather functions that take explicit LOD and/or b= ias argument values can be used with a given image format, add VkImageFormatProperties2 to the pNext chain of the VkPhysicalDeviceImageFormatInfo2 stru= cture and VkTextureLODGatherFormatPropertiesAM= D to the pNext chain of the VkImageFormatProperties2 structure.

The VkTextureLODGatherFormatPropertiesAMD structure is defi= ned as:

typedef struct VkTextureLODGath=
erFormatPropertiesAMD {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           supportsTextureGatherLODBiasAMD;
} VkTextureLODGatherFormatPropertiesAMD;
  • sType is the type of this structure.

  • pNext is NULL.

  • supportsTextureGatherLODBiasAMD tells if the image format c= an be used with texture gather bias/LOD functions, as introduced by the VK_AMD_texture_gather_bias_lod extension. This field is set by the implementation. User-specified value is ignored.

To determine the image capabilities compatible with an external memory handle type, add VkPhysicalDeviceE= xternalImageFormatInfo to the pNext chain of the VkPhysica= lDeviceImageFormatInfo2 structure and VkExternalImageFormatProperties to the pNext = chain of the VkImageFormatProperties2 structure.

The VkPhysicalDeviceExternalImageFormatInfo structure is de= fined as:

typedef struct VkPhysicalDevice=
ExternalImageFormatInfo {
    VkStructureType                       sType;
    const void*                           pNext;
    VkExternalMemoryHandleTypeFlagBits    handleType;
} VkPhysicalDeviceExternalImageFormatInfo;

or the equivalent

typedef VkPhysicalDeviceExternalImageFormatInfo VkPhysicalDevi=
ceExternalImageFormatInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • handleType is a VkExter= nalMemoryHandleTypeFlagBits value specifying the memory handle type that will be used with the memory associated with the image.

If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will behave as if VkPhysicalDevice= ExternalImageFormatInfo was not present, and VkExternalImageFormatProperti= es will be ignored.

If handleType is not compatible with the format, type, tiling, usage, and flags specified i= n VkPhysicalDeviceImageFormatInfo2, the= n vkGetPhysicalDeviceImageFormatPr= operties2 returns VK_ERROR_FORMAT_NOT_SUPPORTED.

Valid Usage (Implicit)
  • = sType must be VK_STRUC= TURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO

  • If handleType is not 0, handleType= must be a valid VkExternalMemoryHandleTypeFlagBits value

Possible values of VkPhysicalDeviceExternalImageForma= tInfo::handleType, specifying an external memory handle type, are:

typedef enum VkExternalMemoryHa=
ndleTypeFlagBits {
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT =3D 0x=
00000001,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT =3D 0x00000002,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT =3D 0x00000004,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT =3D 0x00000008,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT =3D 0x00000010,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT =3D 0=
x00000020,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT =3D 0x00000040,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT =3D =
0x00000200,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID =3D =
0x00000400,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT =3D 0x00000080,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT =3D <=
span class=3D"hex">0x00000100,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR =3D VK_EXTERNAL_MEMORY=
_HANDLE_TYPE_OPAQUE_FD_BIT,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR =3D VK_EXTERNAL_MEM=
ORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR =3D VK_EXTERNAL=
_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR =3D VK_EXTERNAL_ME=
MORY_HANDLE_TYPE_D3D11_TEXTURE_BIT,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR =3D VK_EXTERNA=
L_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR =3D VK_EXTERNAL_MEMOR=
Y_HANDLE_TYPE_D3D12_HEAP_BIT,
    VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR =3D VK_EXTERNAL_M=
EMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT,
} VkExternalMemoryHandleTypeFlagBits;

or the equivalent

typedef VkExternalMemoryHandleTypeFlagBits VkExternalMemoryHan=
dleTypeFlagBitsKHR;
  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT specifies a PO= SIX file descriptor handle that has only limited valid usage outside of Vulkan and other compatible APIs. It must be compatible with the POSIX syst= em calls dup, dup2, close, and the non-standard system call dup3. Additionally, it must be transportable ov= er a socket using an SCM_RIGHTS control message. It owns a reference to the underlying memory resource represented by its Vulkan memory object.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT specifies a= n NT handle that has only limited valid usage outside of Vulkan and other compatible APIs. It must be compatible with the functions = DuplicateHandle, CloseHandle, CompareObjectHandles, GetHandleInformation, and SetHandleInformation. It owns a reference to the underlying memory resource represented by its Vulkan memory object.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT specifi= es a global share handle that has only limited valid usage outside of Vulkan and other compatible APIs. It is not compatible with any native APIs. It does not own a reference to the underlying memory resource represented its Vulkan memory object, and will therefore become invalid when all Vulkan memory objects associated with it are destroyed.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT specifies = an NT handle returned by IDXGIResource1::CreateSharedHandle referring to a Direct3D 10 or 11 texture resource. It owns a reference to the memory used by the Direct3D resource.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT specif= ies a global share handle returned by IDXGIResource::GetShared= Handle referring to a Direct3D 10 or 11 texture resource. It does not own a reference to the underlying Direct3D resource, and will therefore become invalid when all Vulkan memory objects and Direct3D resources associated with it are destroyed.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT specifies an = NT handle returned by ID3D12Device::CreateSharedHandle referring to a Direct3D 12 heap resource. It owns a reference to the resources used by the Direct3D heap.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT specifies= an NT handle returned by ID3D12Device::CreateSharedHandle referring to a Direct3D 12 committed resource. It owns a reference to the memory used by the Direct3D resource.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT spec= ifies a host pointer returned by a host memory allocation command. It does not own a reference to the underlying memory resource, and will therefore become invalid if the host memory is freed.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT<= /code> specifies a host pointer to host mapped foreign memory. It does not own a reference to the underlying memory resource, and will therefore become invalid if the foreign memory is unmapped or otherwise becomes no longer available.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT is a file descriptor for a Linux dma_buf. It owns a reference to the underlying memory resource represented by its Vulkan memory object.

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID= specifies an AHardwareBuffer object defined by the Android NDK= . See Android Hardware Buffers for more details of this handle type.

Some external memory handle types can only be shared within the same underlying physical device and/or the same driver version, as defined in th= e following table:

Table 70. External memory handle types compatibili= ty

Han= dle type

VkPhysicalDeviceIDProperties::driverUUID

VkPhysicalDeviceIDProperties::deviceUUID

VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT

No = restriction

No = restriction

VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT=

No = restriction

No = restriction

VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT

No = restriction

No = restriction

VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID

No = restriction

No = restriction

Note

The above table does not restrict the drivers and devices with which VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT and VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT may be shared, as these handle types inherently mean memory that does not come from the same device, as they import memory from the host or a foreign device, respectively.

Note

Even though the above table does not restrict the drivers and devices wi= th which VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT may be shared, query mechanisms exist in the Vulkan API that prevent the import of incompatible dma-bufs (such as vkGetMemoryFdPro= pertiesKHR) and that prevent incompatible usage of dma-bufs (such as VkPhysicalDeviceExternalBufferInfoKH= R and VkPhysicalDeviceExternalImageFo= rmatInfoKHR).

typedef VkFlags VkExternalMemoryHandleTypeFlags;

or the equivalent

typedef VkExternalMemoryHandleTypeFlags VkExternalMemoryHandle=
TypeFlagsKHR;

VkExternalMemoryHandleTypeFlags is a bitmask type for setti= ng a mask of zero or more VkExternalMemoryHandleT= ypeFlagBits.

The VkExternalImageFormatProperties structure is defined as= :

typedef struct VkExternalImageF=
ormatProperties {
    VkStructureType               sType;
    void*                         pNext;
    VkExternalMemoryProperties    externalMemoryProperties;
} VkExternalImageFormatProperties;

or the equivalent

typedef VkExternalImageFormatProperties VkExternalImageFormatP=
ropertiesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • externalMemoryProperties is an instance of the VkExternalMemoryProperties structure specif= ying various capabilities of the external handle type when used with the specified image creation parameters.

Valid Usage (Implicit)
  • sT= ype must be VK_STRUCTURE_TYP= E_EXTERNAL_IMAGE_FORMAT_PROPERTIES

The VkExternalMemoryProperties structure is defined as:

typedef struct VkExternalMemory=
Properties {
    VkExternalMemoryFeatureFlags       externalMemoryFeatures;
    VkExternalMemoryHandleTypeFlags    exportFromImportedHandleTypes;
    VkExternalMemoryHandleTypeFlags    compatibleHandleTypes;
} VkExternalMemoryProperties;

or the equivalent

typedef VkExternalMemoryProperties VkExternalMemoryPropertiesK=
HR;

compatibleHandleTypes must include at least handleType. Inclusion of a handle type in compatibleHandleTypes does not i= mply the values returned in VkImageFormatProperties2 w= ill be the same when VkPhysicalDeviceExternalImageForma= tInfo::handleType is set to that type. The application is responsible for querying the capabilities of all handle types intended for concurrent use in a single image and intersecting them t= o obtain the compatible set of capabilities.

Bits which may be set in VkExternalMemoryProperties::externalM= emoryFeatures, specifying features of an external memory handle type, are:

typedef enum VkExternalMemoryFe=
atureFlagBits {
    VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT =3D 0=
x00000001,
    VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT =3D 0x000=
00002,
    VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT =3D 0x000=
00004,
    VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR =3D VK_EXTERNAL_MEMOR=
Y_FEATURE_DEDICATED_ONLY_BIT,
    VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR =3D VK_EXTERNAL_MEMORY_FE=
ATURE_EXPORTABLE_BIT,
    VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR =3D VK_EXTERNAL_MEMORY_FE=
ATURE_IMPORTABLE_BIT,
} VkExternalMemoryFeatureFlagBits;

or the equivalent

typedef VkExternalMemoryFeatureFlagBits VkExternalMemoryFeatur=
eFlagBitsKHR;
  • VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT specifies tha= t images or buffers created with the specified parameters and handle type must use the mechanisms defined in the VK_NV_dedicated_allocation extension to create (or import) a dedicated allocation for the image or buffer.

  • VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT specifies that ha= ndles of this type can be exported from Vulkan = memory objects.

  • VK_INTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT specifies that ha= ndles of this type can be imported as Vulkan me= mory objects.

Because their semantics in external APIs roughly align with that of an i= mage or buffer with a dedicated allocation in Vulkan, implementations are required to report VK_EXTERNAL_MEMO= RY_FEATURE_DEDICATED_ONLY_BIT for the following external handle types:

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT

  • VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID= for images only

Implementations must not report VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT for buffers with external handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID.

typedef VkFlags VkExternalMemoryFeatureFlags;

or the equivalent

typedef VkExternalMemoryFeatureFlags VkExternalMemoryFeatureFl=
agsKHR;

VkExternalMemoryFeatureFlags is a bitmask type for setting = a mask of zero or more VkExternalMemoryFeatureFlagBi= ts.

To determine the number of combined image samplers required to support a multi-planar format, add VkS= amplerYcbcrConversionImageFormatProperties to the pNext chain of the VkImageFor= matProperties2 structure in a call to vkGetPhysicalDeviceImageFormatProperties2.

The VkSamplerYcbcrConversionImageFormatProperties structure= is defined as:

typedef struct VkSamplerYcbcrCo=
nversionImageFormatProperties {
    VkStructureType    sType;
    void*              pNext;
    uint32_t           combinedImageSamplerDescriptorCount;
} VkSamplerYcbcrConversionImageFormatProperties;

or the equivalent

typedef VkSamplerYcbcrConversionImageFormatProperties VkSample=
rYcbcrConversionImageFormatPropertiesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • combinedImageSamplerDescriptorCount is the number of combin= ed image sampler descriptors that the implementation uses to access the format.

Valid Usage (Implicit)
  • sType must be VK= _STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES

combinedImageSamplerDescriptorCount affects only the count = towards the maxDescriptorSetSamplers, maxDescriptorSetSampledImages<= /code>, maxPerStageDescriptorSamplers, and maxPerStageDescriptorSampledImages limits, and does not affect= binding numbers in the VkDescriptorSetLayoutBinding.

combinedImageSamplerDescriptorCount is a number between 1 a= nd the number of planes in the format.

typedef struct VkAndroidHardwar=
eBufferUsageANDROID {
    VkStructureType    sType;
    void*              pNext;
    uint64_t           androidHardwareBufferUsage;
} VkAndroidHardwareBufferUsageANDROID;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • androidHardwareBufferUsage returns the the Android hardware= buffer usage flags.

The androidHardwareBufferUsage field must include Android hardware buffer usage flags listed in the AHardwareBuffer Usage Equivalence table when the corresponding Vulkan image usage or image creation flags are included in the usage or flags= fields of VkPhysicalDeviceImageFormatInfo2. It must include at least one GPU usage fl= ag (AHARDWAREBUFFER_USAGE_GPU_*), even if none of the correspondi= ng Vulkan usages or flags are requested.

Note

Requiring at least one GPU usage flag ensures that Android hardware buff= er memory will be allocated in a memory pool accessible to the Vulkan implementation, and that specializing the memory layout based on usage flag= s does not prevent it from being compatible with Vulkan. Implementations may avoid unnecessary res= trictions caused by this requirement by using vendor usage flags to indicate that only the Vulkan uses indicated in VkImageFormatProperties2 ar= e required.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID

32.5.1. Supported Sample Counts=

vkGetPhysicalDeviceImageFormatProperties returns a bitmask = of VkSampleCountFlagBits in sampleCounts specifying the supported sample counts for the image parameters.

sampleCounts will be set to VK_SAMPLE_COUNT_1_BIT if at least one of the following conditions is true:

Otherwise, the bits set in sampleCounts will be the sample = counts supported for the specified values of usage and format. For each bit set in usage, the supported sample counts relate = to the limits in VkPhysicalDeviceLimits as follows:

  • If usage includes VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT= and format is a floating- or fixed-point color format, a superset = of VkPhysicalDeviceLimits::framebufferColorSampleCounts

  • If usage includes VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, and format<= /code> includes a depth aspect, a superset of VkPhysicalDeviceLimits::framebufferDepthSampleCounts

  • If usage includes VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, and format<= /code> includes a stencil aspect, a superset of VkPhysicalDeviceLimits::framebufferStencilSampleCounts

  • If usage includes VK_IMAGE_USAGE_SAMPLED_BIT, = and format includes a color aspect, a superset of VkPhysicalDeviceLimits::sampledImageColorSampleCounts

  • If usage includes VK_IMAGE_USAGE_SAMPLED_BIT, = and format includes a depth aspect, a superset of VkPhysicalDeviceLimits::sampledImageDepthSampleCounts

  • If usage includes VK_IMAGE_USAGE_SAMPLED_BIT, = and format is an integer format, a superset of VkPhysicalDeviceLimits::sampledImageIntegerSampleCounts<= /code>

  • If usage includes VK_IMAGE_USAGE_STORAGE_BIT, = a superset of VkPhysicalDeviceLimits::storageImageSampleCounts<= /p>

If multiple bits are set in usage, sampleCounts will be the intersection of the per-usage values described above.

If none of the bits described above are set in usage, then = there is no corresponding limit in VkPhysicalDeviceLimits. In this case, sampleCounts must include at least VK_SAMPLE_COUNT_1_BIT.

32.5.2. Allowed Extent Values Based = On Image Type

Implementations may support extent val= ues larger than the required minimum/maximum values for certain types of images subject to the constraints below.

Note

Implementations must support images wi= th dimensions up to the required minimum/maximum values for all types o= f images. It follows that the query for additional capabilities must return extent values that are at least as large as the required values.

For VK_IMAGE_TYPE_1D:

  • maxExtent.width =E2=89=A5 VkPhysicalDeviceLimits.maxImageDimension1= D

  • maxExtent.height =3D 1

  • maxExtent.depth =3D 1

For VK_IMAGE_TYPE_2D when flags does not conta= in VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:

For VK_IMAGE_TYPE_2D when flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:

For VK_IMAGE_TYPE_3D:

32.6. Additional Buffer Capabili= ties

In addition to the capabilities described in the previous sections (Limits and Formats), implementations may support additional buffer capabilities.

To query the external handle types supported by buffers, call:

void vkGetPhysicalDeviceExternalBufferProperties(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceExternalBufferIn=
fo*   pExternalBufferInfo,
    VkExternalBufferProperties*                 pExternalBufferProperties);=

or the equivalent command

void vkGetPhysicalDeviceExternalBufferPropertiesKHR(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceExternalBufferIn=
fo*   pExternalBufferInfo,
    VkExternalBufferProperties*                 pExternalBufferProperties);=
  • physicalDevice is the physical device from which to query t= he buffer capabilities.

  • pExternalBufferInfo points to an instance of the VkPhysicalDeviceExternalBufferInfo = structure, describing the parameters that would be consumed by vkCreateBuffer.

  • pExternalBufferProperties points to an instance of the VkExternalBufferProperties structure in whi= ch capabilities are returned.

Valid Usage (Implicit)
  • physicalDevice must<= /strong> be a valid VkPhysicalDevice handle

  • pExternalBufferInfo must be a valid pointer to a valid VkPhysicalDeviceExte= rnalBufferInfo structure

  • pExternalBufferProperties must be a valid pointer to a VkExternalBuff= erProperties structure

The VkPhysicalDeviceExternalBufferInfo structure is defined= as:

typedef struct VkPhysicalDevice=
ExternalBufferInfo {
    VkStructureType                       sType;
    const void*                           pNext;
    VkBufferCreateFlags                   flags;
    VkBufferUsageFlags                    usage;
    VkExternalMemoryHandleTypeFlagBits    handleType;
} VkPhysicalDeviceExternalBufferInfo;

or the equivalent

typedef VkPhysicalDeviceExternalBufferInfo VkPhysicalDeviceExt=
ernalBufferInfoKHR;
Valid Usage (Implicit)

32.7. Optional Semaphore Capabi= lities

Semaphores may support import and expo= rt of their payload to external handles. To query the external handle types supported by semaphores, call:

void vkGetPhysicalDeviceExternalSemaphoreProperties(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceExternalSemaphor=
eInfo* pExternalSemaphoreInfo,
    VkExternalSemaphoreProperties*              pExternalSemaphorePropertie=
s);

or the equivalent command

void vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceExternalSemaphor=
eInfo* pExternalSemaphoreInfo,
    VkExternalSemaphoreProperties*              pExternalSemaphorePropertie=
s);
Valid Usage (Implicit)
  • physicalDevice mu= st be a valid VkPhysicalDevice handle

  • pExternalSemaphoreInfo must be a valid pointer to a valid VkPhysicalD= eviceExternalSemaphoreInfo structure

  • pExternalSemaphoreProperties= must be a valid pointer to a VkExt= ernalSemaphoreProperties structure

The VkPhysicalDeviceExternalSemaphoreInfo structure is defi= ned as:

typedef struct VkPhysicalDevice=
ExternalSemaphoreInfo {
    VkStructureType                          sType;
    const void*                              pNext;
    VkExternalSemaphoreHandleTypeFlagBits    handleType;
} VkPhysicalDeviceExternalSemaphoreInfo;

or the equivalent

typedef VkPhysicalDeviceExternalSemaphoreInfo VkPhysicalDevice=
ExternalSemaphoreInfoKHR;
  • sType is the type of this structure

  • pNext is NULL or a pointer to an extension-specific structu= re.

  • handleType is a VkEx= ternalSemaphoreHandleTypeFlagBits value specifying the external semaphore handle type for which capabilities will be returned.

Valid Usage (Implicit)

Bits which may be set in VkPhysicalDeviceExternalSemaphoreInf= o::handleType, specifying an external semaphore handle type, are:

typedef enum VkExternalSemaphor=
eHandleTypeFlagBits {
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT =3D 0x00000001,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT =3D 0x00000002,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT =3D 0x00000004,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT =3D 0x00000008,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT =3D 0=
x00000010,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR =3D VK_EXTERNAL_SEM=
APHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR =3D VK_EXTERNAL_=
SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR =3D VK_EXTER=
NAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR =3D VK_EXTERNAL_S=
EMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT,
    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR =3D VK_EXTERNAL_SEMAP=
HORE_HANDLE_TYPE_SYNC_FD_BIT,
} VkExternalSemaphoreHandleTypeFlagBits;

or the equivalent

typedef VkExternalSemaphoreHandleTypeFlagBits VkExternalSemaph=
oreHandleTypeFlagBitsKHR;
  • VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT specifies a= POSIX file descriptor handle that has only limited valid usage outside of Vulkan and other compatible APIs. It must be compatible with the POSIX syst= em calls dup, dup2, close, and the non-standard system call dup3. Additionally, it must be transportable ov= er a socket using an SCM_RIGHTS control message. It owns a reference to the underlying synchronization primitive represented by its Vulkan semaphore object.

  • VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT specifie= s an NT handle that has only limited valid usage outside of Vulkan and other compatible APIs. It must be compatible with the functions = DuplicateHandle, CloseHandle, CompareObjectHandles, GetHandl= eInformation, and SetHandleInformation. It owns a reference to the underlying synchronization primitive represented by its Vulkan semaphore object.

  • VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT spec= ifies a global share handle that has only limited valid usage outside of Vulkan and other compatible APIs. It is not compatible with any native APIs. It does not own a reference to the underlying synchronization primitive represented its Vulkan semaphore object, and will therefore become invalid when all Vulkan semaphore objects associated with it are destroyed.

  • VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT specifies= an NT handle returned by ID3D12Device::CreateSharedHandle referring to a Direct3D 12 fence. It owns a reference to the underlying synchronization primitive associated with the Direct3D fence.

  • VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT specifies a P= OSIX file descriptor handle to a Linux Sync File or Android Fence object. It can be used with any native API accepting a valid sync file or fence as input. It owns a reference to the underlying synchronization primitive associated with the file descriptor. Implementations which support importing this handle type must accept any type of sync or fence FD supported by the native system they are running on.

Note

Handles of type VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT generated by the implementation may represent either Linux Sync Files or Android Fences at the implementation=E2=80=99s discretion. Applications should only use operations d= efined for both types of file descriptors, unless they know via means external to Vulkan the type of the file descriptor, or are prepared to deal with the system-defined operation failures resulting from using the wrong type.

Some external semaphore handle types can only be shared within the same underlying physical device and/or the same driver version, as defined in th= e following table:

Table 71. External semaphore handle types compatib= ility

Han= dle type

VkPhysicalDeviceIDProperties::driverUUID

VkPhysicalDeviceIDProperties::deviceUUID

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT

No = restriction

No = restriction

typedef VkFlags VkExternalSemaphoreHandleTypeFlags;

or the equivalent

typedef VkExternalSemaphoreHandleTypeFlags VkExternalSemaphore=
HandleTypeFlagsKHR;

VkExternalSemaphoreHandleTypeFlags is a bitmask type for se= tting a mask of zero or more VkExternalSemap= horeHandleTypeFlagBits.

The VkExternalSemaphoreProperties structure is defined as:<= /p>

typedef struct VkExternalSemaph=
oreProperties {
    VkStructureType                       sType;
    void*                                 =
pNext;
    VkExternalSemaphoreHandleTypeFlags    exportFromImportedHandleTypes;
    VkExternalSemaphoreHandleTypeFlags    compatibleHandleTypes;
    VkExternalSemaphoreFeatureFlags       externalSemaphoreFeatures;
} VkExternalSemaphoreProperties;

or the equivalent

typedef VkExternalSemaphoreProperties VkExternalSemaphorePrope=
rtiesKHR;

If handleType is not supported by the implementation, then VkExternalSemaphoreProperties::ext= ernalSemaphoreFeatures will be set to zero.

Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= EXTERNAL_SEMAPHORE_PROPERTIES

  • pNex= t must be NULL

Possible values of VkExternalSemaphoreProperties::ext= ernalSemaphoreFeatures, specifying the features of an external semaphore handle type, are:

typedef enum VkExternalSemaphor=
eFeatureFlagBits {
    VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT =3D 0x=
00000001,
    VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT =3D 0x=
00000002,
    VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR =3D VK_EXTERNAL_SEMAPH=
ORE_FEATURE_EXPORTABLE_BIT,
    VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR =3D VK_EXTERNAL_SEMAPH=
ORE_FEATURE_IMPORTABLE_BIT,
} VkExternalSemaphoreFeatureFlagBits;

or the equivalent

typedef VkExternalSemaphoreFeatureFlagBits VkExternalSemaphore=
FeatureFlagBitsKHR;
  • VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT specifies that handles of this type can be exported from= Vulkan semaphore objects.

  • VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT specifies that handles of this type can be imported as V= ulkan semaphore objects.

typedef VkFlags VkExternalSemaphoreFeatureFlags;

or the equivalent

typedef VkExternalSemaphoreFeatureFlags VkExternalSemaphoreFea=
tureFlagsKHR;

VkExternalSemaphoreFeatureFlags is a bitmask type for setti= ng a mask of zero or more VkExternalSemaphoreFeat= ureFlagBits.

32.8. Optional Fence Capabilities

Fences may support import and export o= f their payload to external handles. To query the external handle types supported by fences, call:

void vkGetPhysicalDeviceExternalFenceProperties(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceExternalFenceInf=
o*    pExternalFenceInfo,
    VkExternalFenceProperties*                  pExternalFenceProperties);<=
/code>

or the equivalent command

void vkGetPhysicalDeviceExternalFencePropertiesKHR(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceExternalFenceInf=
o*    pExternalFenceInfo,
    VkExternalFenceProperties*                  pExternalFenceProperties);<=
/code>
  • physicalDevice is the physical device from which to query t= he fence capabilities.

  • pExternalFenceInfo points to an instance of the VkPhysicalDeviceExternalFenceInfo st= ructure, describing the parameters that would be consumed by vkCreateFence.

  • pExternalFenceProperties points to an instance of the VkExternalFenceProperties structure in which= capabilities are returned.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pExternalFenceInfo must be a valid pointer to a valid VkPhysicalDeviceExterna= lFenceInfo structure

  • pExternalFenceProperties must be a valid pointer to a VkExternalFencePr= operties structure

The VkPhysicalDeviceExternalFenceInfo structure is defined = as:

typedef struct VkPhysicalDevice=
ExternalFenceInfo {
    VkStructureType                      sType;
    const void*                          pNext;
    VkExternalFenceHandleTypeFlagBits    handleType;
} VkPhysicalDeviceExternalFenceInfo;

or the equivalent

typedef VkPhysicalDeviceExternalFenceInfo VkPhysicalDeviceExte=
rnalFenceInfoKHR;
  • sType is the type of this structure

  • pNext is NULL or a pointer to an extension-specific structu= re.

  • handleType is a VkExtern= alFenceHandleTypeFlagBits value indicating an external fence handle type for which capabilities will be returned.

Note

Handles of type VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT g= enerated by the implementation may represent either Linux Sync Files or Android Fences at the implementation=E2=80=99s discretion. Applications should only use operations d= efined for both types of file descriptors, unless they know via means external to Vulkan the type of the file descriptor, or are prepared to deal with the system-defined operation failures resulting from using the wrong type.

Valid Usage (Implicit)

Bits which may be set in VkPhysicalDeviceExternalFenceInfo::<= code>handleType, and in the exportFromImportedHandleTypes and compatibleHandleTypes<= /code> members of VkExternalFenceProperties, to indicate ex= ternal fence handle types, are:

typedef enum VkExternalFenceHan=
dleTypeFlagBits {
    VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT =3D 0x0=
0000001,
    VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT =3D =
0x00000002,
    VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT =3D 0x00000004,
    VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT =3D 0x000=
00008,
    VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR =3D VK_EXTERNAL_FENCE_H=
ANDLE_TYPE_OPAQUE_FD_BIT,
    VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR =3D VK_EXTERNAL_FENC=
E_HANDLE_TYPE_OPAQUE_WIN32_BIT,
    VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR =3D VK_EXTERNAL_=
FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
    VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR =3D VK_EXTERNAL_FENCE_HAN=
DLE_TYPE_SYNC_FD_BIT,
} VkExternalFenceHandleTypeFlagBits;

or the equivalent

typedef VkExternalFenceHandleTypeFlagBits VkExternalFenceHandl=
eTypeFlagBitsKHR;
  • VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT specifies a POS= IX file descriptor handle that has only limited valid usage outside of Vulkan and other compatible APIs. It must be compatible with the POSIX syst= em calls dup, dup2, close, and the non-standard system call dup3. Additionally, it must be transportable ov= er a socket using an SCM_RIGHTS control message. It owns a reference to the underlying synchronization primitive represented by its Vulkan fence object.

  • VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT specifies an= NT handle that has only limited valid usage outside of Vulkan and other compatible APIs. It must be compatible with the functions = DuplicateHandle, CloseHandle, CompareObjectHandles, GetHandl= eInformation, and SetHandleInformation. It owns a reference to the underlying synchronization primitive represented by its Vulkan fence object.

  • VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT specifie= s a global share handle that has only limited valid usage outside of Vulkan and other compatible APIs. It is not compatible with any native APIs. It does not own a reference to the underlying synchronization primitive represented by its Vulkan fence object, and will therefore become invalid when all Vulkan fence objects associated with it are destroyed.

  • VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT specifies a POSIX= file descriptor handle to a Linux Sync File or Android Fence. It can be used with any native API accepting a valid sync file or fence as input. It owns a reference to the underlying synchronization primitive associated with the file descriptor. Implementations which support importing this handle type must accept any type of sync or fence FD supported by the native system they are running on.

Some external fence handle types can only be shared within the same underlying physical device and/or the same driver version, as defined in th= e following table:

Table 72. External fence handle types compatibilit= y

Han= dle type

VkPhysicalDeviceIDProperties::driverUUID

VkPhysicalDeviceIDProperties::deviceUUID

VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT

Mus= t match

Mus= t match

VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT

No = restriction

No = restriction

typedef VkFlags VkExternalFenceHandleTypeFlags;

or the equivalent

typedef VkExternalFenceHandleTypeFlags VkExternalFenceHandleTy=
peFlagsKHR;

VkExternalFenceHandleTypeFlags is a bitmask type for settin= g a mask of zero or more VkExternalFenceHandleTypeFl= agBits.

The VkExternalFenceProperties structure is defined as:

typedef struct VkExternalFenceP=
roperties {
    VkStructureType                   sType;
    void*                             pNex=
t;
    VkExternalFenceHandleTypeFlags    exportFromImportedHandleTypes;
    VkExternalFenceHandleTypeFlags    compatibleHandleTypes;
    VkExternalFenceFeatureFlags       externalFenceFeatures;
} VkExternalFenceProperties;

or the equivalent

typedef VkExternalFenceProperties VkExternalFencePropertiesKHR=
;

If handleType is not supported by the implementation, then VkExternalFenceProperties::externalFen= ceFeatures will be set to zero.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_EXTE= RNAL_FENCE_PROPERTIES

  • pNext must be NULL

Bits which may be set in VkExternalFenceProperties::externalFen= ceFeatures, indicating features of a fence external handle type, are:

typedef enum VkExternalFenceFea=
tureFlagBits {
    VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT =3D 0x0000=
0001,
    VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT =3D 0x0000=
0002,
    VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR =3D VK_EXTERNAL_FENCE_FEAT=
URE_EXPORTABLE_BIT,
    VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR =3D VK_EXTERNAL_FENCE_FEAT=
URE_IMPORTABLE_BIT,
} VkExternalFenceFeatureFlagBits;

or the equivalent

typedef VkExternalFenceFeatureFlagBits VkExternalFenceFeatureF=
lagBitsKHR;
  • VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT specifies handles = of this type can be exported from Vulkan fence ob= jects.

  • VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT specifies handles = of this type can be imported to Vulkan fence obje= cts.

typedef VkFlags VkExternalFenceFeatureFlags;

or the equivalent

typedef VkExternalFenceFeatureFlags VkExternalFenceFeatureFlag=
sKHR;

VkExternalFenceFeatureFlags is a bitmask type for setting a= mask of zero or more VkExternalFenceFeatureFlagBits= .

33. Debugging

To aid developers in tracking down errors in the application=E2=80=99s u= se of Vulkan, particularly in combination with an external debugger or profiler, debugging extensions may be available.

The VkObjectType enumeration defines values, each of w= hich corresponds to a specific Vulkan handle type. These values can be used to associate deb= ug information with a particular type of object through one or more extensions.

typedef enum VkObjectType {
    VK_OBJECT_TYPE_UNKNOWN =3D 0,
    VK_OBJECT_TYPE_INSTANCE =3D 1,
    VK_OBJECT_TYPE_PHYSICAL_DEVICE =3D 2,
    VK_OBJECT_TYPE_DEVICE =3D 3,
    VK_OBJECT_TYPE_QUEUE =3D 4,
    VK_OBJECT_TYPE_SEMAPHORE =3D 5,
    VK_OBJECT_TYPE_COMMAND_BUFFER =3D 6,
    VK_OBJECT_TYPE_FENCE =3D 7,
    VK_OBJECT_TYPE_DEVICE_MEMORY =3D 8,
    VK_OBJECT_TYPE_BUFFER =3D 9,
    VK_OBJECT_TYPE_IMAGE =3D 10,
    VK_OBJECT_TYPE_EVENT =3D 11,
    VK_OBJECT_TYPE_QUERY_POOL =3D 12,
    VK_OBJECT_TYPE_BUFFER_VIEW =3D 13,
    VK_OBJECT_TYPE_IMAGE_VIEW =3D 14,
    VK_OBJECT_TYPE_SHADER_MODULE =3D 15,
    VK_OBJECT_TYPE_PIPELINE_CACHE =3D 16,
    VK_OBJECT_TYPE_PIPELINE_LAYOUT =3D 17,
    VK_OBJECT_TYPE_RENDER_PASS =3D 18,
    VK_OBJECT_TYPE_PIPELINE =3D 19,
    VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT =3D 20,
    VK_OBJECT_TYPE_SAMPLER =3D 21,
    VK_OBJECT_TYPE_DESCRIPTOR_POOL =3D 22,
    VK_OBJECT_TYPE_DESCRIPTOR_SET =3D 23,
    VK_OBJECT_TYPE_FRAMEBUFFER =3D 24,
    VK_OBJECT_TYPE_COMMAND_POOL =3D 25,
    VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION =3D 100=
0156000,
    VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE =3D 1=
000085000,
    VK_OBJECT_TYPE_SURFACE_KHR =3D 1000000000,
    VK_OBJECT_TYPE_SWAPCHAIN_KHR =3D 1000001000,
    VK_OBJECT_TYPE_DISPLAY_KHR =3D 1000002000,
    VK_OBJECT_TYPE_DISPLAY_MODE_KHR =3D 1000002001<=
/span>,
    VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT =3D 10=
00011000,
    VK_OBJECT_TYPE_OBJECT_TABLE_NVX =3D 1000086000<=
/span>,
    VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX =3D 1000086001,
    VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT =3D 10=
00128000,
    VK_OBJECT_TYPE_VALIDATION_CACHE_EXT =3D 1000160=
000,
    VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR =3D VK_OBJECT_TYPE_DESCRI=
PTOR_UPDATE_TEMPLATE,
    VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR =3D VK_OBJECT_TYPE_SAMPLER_=
YCBCR_CONVERSION,
} VkObjectType;
Table 73. VkObjectType and Vulkan Handle Relations= hip
VkObjectType<= /a> Vulkan Handle Type

VK_OBJECT_TYPE_UNKNOWN

Unk= nown/Undefined Handle

VK_OBJECT_TYPE_INSTANCE

VkInstance

VK_OBJECT_TYPE_PHYSICAL_DEVICE

VkPhysicalDevice

VK_OBJECT_TYPE_DEVICE

VkDevice

VK_OBJECT_TYPE_QUEUE

VkQueue

VK_OBJECT_TYPE_SEMAPHORE

VkSemaphore

VK_OBJECT_TYPE_COMMAND_BUFFER

VkCommandBuffer

VK_OBJECT_TYPE_FENCE

VkFence

VK_OBJECT_TYPE_DEVICE_MEMORY

VkDeviceMemory

VK_OBJECT_TYPE_BUFFER

VkBuffer

VK_OBJECT_TYPE_IMAGE

VkImage

VK_OBJECT_TYPE_EVENT

VkEvent

VK_OBJECT_TYPE_QUERY_POOL

VkQueryPool

VK_OBJECT_TYPE_BUFFER_VIEW

VkBufferView

VK_OBJECT_TYPE_IMAGE_VIEW

VkImageView

VK_OBJECT_TYPE_SHADER_MODULE

VkShaderModule

VK_OBJECT_TYPE_PIPELINE_CACHE

VkPipelineCache

VK_OBJECT_TYPE_PIPELINE_LAYOUT

VkPipelineLayout

VK_OBJECT_TYPE_RENDER_PASS

VkRenderPass

VK_OBJECT_TYPE_PIPELINE

VkPipeline

VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT

VkDescriptorSetLayout

VK_OBJECT_TYPE_SAMPLER

VkSampler

VK_OBJECT_TYPE_DESCRIPTOR_POOL

VkDescriptorPool

VK_OBJECT_TYPE_DESCRIPTOR_SET

VkDescriptorSet

VK_OBJECT_TYPE_FRAMEBUFFER

VkFramebuffer

VK_OBJECT_TYPE_COMMAND_POOL

VkCommandPool

VK_OBJECT_TYPE_SURFACE_KHR

VkSurfaceKHR

VK_OBJECT_TYPE_SWAPCHAIN_KHR

VkSwapchainKHR

VK_OBJECT_TYPE_DISPLAY_KHR

VkDisplayKHR

VK_OBJECT_TYPE_DISPLAY_MODE_KHR

VkDisplayModeKHR

VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT

VkDebugReportCallbackEXT

VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE

VkDescriptorUpdateTemplate

VK_OBJECT_TYPE_OBJECT_TABLE_NVX

VkObjectTableNVX

VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX

VkIndirectCommandsLayoutNVX

VK_OBJECT_TYPE_VALIDATION_CACHE_EXT

VkValidationCacheEXT

If this Specification was generated with any such extensions included, t= hey will be described in the remainder of this chapter.

33.1. Debug Utilities

Vulkan provides flexible debugging utilities for debugging an applicatio= n.

The Object Debug Annotation secti= on describes how to associate either a name or binary data with a specific Vulkan object.

The Queue Labels section describes how to annotate and group the work submitted to a queue.

The Command Buffer Labels section describes how to associate logical elements of the scene with commands in a VkCommandBuffer.

The Debug Messengers section describes h= ow to create debug messenger objects associated with an application supplied callback to capture debug messages from a variety of Vulkan components.

33.1.1. Object Debug Annotatio= n

It can be useful for an application to provide its own content relative = to a specific Vulkan object. The following commands allow application developers to associate user-defined information with Vulkan objects.

Object Naming

An object can be provided a user-defined name by calling vkSetDebugUtilsObjectNameEXT as defined below.

VkResult vkSetDebu=
gUtilsObjectNameEXT(
    VkDevice                                    device,
    const VkDebugUtilsObjectNameInfoEXT*  =
      pNameInfo);
  • device is the device that created the object.

  • pNameInfo is a pointer to an instance of the VkDebugUtilsObjectNameInfoEXT structure = specifying the parameters of the name to set on the object.

Valid Usage (Implicit)
  • = device must be a valid VkDev= ice handle

  • pNameInfo must be a valid point= er to a valid VkDebugUtilsObjectNameInfoEXT structure

Host Synchronization
  • Host access to pNameInfo.objectHandle must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDebugUtilsObjectNameInfoEXT structure is defined as:<= /p>

typedef struct VkDebugUtilsObje=
ctNameInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    VkObjectType       objectType;
    uint64_t           objectHandle;
    const =
char*        pObjectName;
} VkDebugUtilsObjectNameInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • objectType is a VkObjectType specifying t= he type of the object to be named.

  • objectHandle is the object to be named.

  • pObjectName is a null-terminated UTF-8 string specifying th= e name to apply to objectHandle.

Applications may change the name assoc= iated with an object simply by calling vkSetDebugUtilsObjectNameEXT again with a new string. If pObjectName is an empty string, then any previously set nam= e is removed.

Valid Usage
Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= DEBUG_UTILS_OBJECT_NAME_INFO_EXT

  • pNex= t must be NULL

  • <= code>objectType must be a valid VkObjectType value

  • = If pObjectName is not NULL, pObjectName must be a null-terminated UTF-8 strin= g

Object Data Association

In addition to setting a name for an object, debugging and validation la= yers may have uses for additional binary data = on a per-object basis that have no other place in the Vulkan API.

For example, a VkShaderModule could have additional debuggi= ng data attached to it to aid in offline shader tracing.

Additional data can be attached to an object by calling vkSetDebugUtilsObjectTagEXT as defined below.

VkResult vkSetDebu=
gUtilsObjectTagEXT(
    VkDevice                                    device,
    const VkDebugUtilsObjectTagInfoEXT*   =
      pTagInfo);
  • device is the device that created the object.

  • pTagInfo is a pointer to an instance of the VkDebugUtilsObjectTagInfoEXT structure sp= ecifying the parameters of the tag to attach to the object.

Valid Usage (Implicit)
  • d= evice must be a valid VkDevi= ce handle

  • pTagInfo must be a valid pointer = to a valid VkDebugUtilsObjectTagInfoEXT structure

Host Synchronization
  • Host access to pTagInfo.objectHandle must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDebugUtilsObjectTagInfoEXT structure is defined as:

typedef struct VkDebugUtilsObje=
ctTagInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    VkObjectType       objectType;
    uint64_t           objectHandle;
    uint64_t           tagName;
    size_t             tagSize;
    const void*        pTag;
} VkDebugUtilsObjectTagInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • objectType is a VkObjectType specifying t= he type of the object to be named.

  • objectHandle is the object to be tagged.

  • tagName is a numerical identifier of the tag.

  • tagSize is the number of bytes of data to attach to the obj= ect.

  • pTag is an array of tagSize bytes containing t= he data to be associated with the object.

The tagName parameter gives a name or identifier to the typ= e of data being tagged. This can be used by debugging layers to easily filter for only data that ca= n be used by that implementation.

Valid Usage
Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_D= EBUG_UTILS_OBJECT_TAG_INFO_EXT

  • pNext= must be NULL

  • objectType must be a valid VkObjectType value

  • pT= ag must be a valid pointer to an a= rray of tagSize bytes

  • tagSize must be greater than 0

33.1.2. Queue Labels

All Vulkan work must be submitted using queues. It is possible for an application to use multiple queues, each containing multiple command buffers, when performing work. It can be useful to identify which queue, or even where in a queue, something has occurred.

To begin identifying a region using a debug label inside a queue, you ma= y use the vkQueueBeginDebugUtilsLabelEXT = command.

Then, when the region of interest has passed, you may end the label regi= on using vkQueueEndDebugUtilsLabelEXT.

Additionally, a single debug label may be inserted at any time using vkQueueInsertDebugUtilsLabelEXT.

A queue debug label region is opened by calling:

void vkQueueBeginDebugUtilsLabelEXT(
    VkQueue                                     queue,
    const VkDebugUtilsLabelEXT*           =
      pLabelInfo);
  • queue is the queue in which to start a debug label region.<= /p>

  • pLabelInfo is a pointer to an instance of the VkDebugUtilsLabelEXT structure specifying the par= ameters of the label region to open.

Valid Usage (Implicit)
  • queue must be a valid VkQue= ue handle

  • = pLabelInfo must be a valid p= ointer to a valid VkDebugUtilsLabelEXT structure

The VkDebugUtilsLabelEXT structure is defined as:

typedef struct VkDebugUtilsLabe=
lEXT {
    VkStructureType    sType;
    const void*        pNext;
    const =
char*        pLabelName;
    float              color[4];
} VkDebugUtilsLabelEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • pLabelName is a pointer to a null-terminated UTF-8 string t= hat contains the name of the label.

  • color is an optional RGBA color value that can be associate= d with the label. A particular implementation may choose to= ignore this color value. The values contain RGBA values in order, in the range 0.0 to 1.0. If all elements in color are set to 0.0 then it is ignored.

Valid Usage (Implicit)
  • sType = must be VK_STRUCTURE_TYPE_DEBUG_UTI= LS_LABEL_EXT

  • pNext = must be NULL

  • pLab= elName must be a null-terminated U= TF-8 string

A queue debug label region is closed by calling:

void vkQueueEndDebugUtilsLabelEXT(
    VkQueue                                     queue);
  • queue is the queue in which a debug label region should be = closed.

The calls to vkQueueBeginDebugUtilsLabel= EXT and vkQueueEndDebugUtilsLabelEXT must be matched and balanced.

Valid Usage
  • There must be an outstanding vkQueu= eBeginDebugUtilsLabelEXT command prior to the vkQueueEndDebugUtilsLabelEXT on the queue=

Valid Usage (Implicit)
  • q= ueue must be a valid VkQueue= handle

A single label can be inserted into a queue by calling:

void vkQueueInsertDebugUtilsLabelEXT(
    VkQueue                                     queue,
    const VkDebugUtilsLabelEXT*           =
      pLabelInfo);
  • queue is the queue into which a debug label will be inserte= d.

  • pLabelInfo is a pointer to an instance of the VkDebugUtilsLabelEXT structure specifying the par= ameters of the label to insert.

Valid Usage (Implicit)
  • queue must be a valid VkQu= eue handle

  • = pLabelInfo must be a valid = pointer to a valid VkDebugUtilsLabelEXT structure

33.1.3. Command Buffer Labels

Typical Vulkan applications will submit many command buffers in each fra= me, with each command buffer containing a large number of individual commands. Being able to logically annotate regions of command buffers that belong together as well as hierarchically subdivide the frame is important to a developer=E2=80=99s ability to navigate the commands viewed holistically.

To identify the beginning of a debug label region in a command buffer, vkCmdBeginDebugUtilsLabelEXT can be used as defined below.

To indicate the end of a debug label region in a command buffer, vkCmdEndDebugUtilsLabelEXT can be used.

To insert a single command buffer debug label inside of a command buffer= , vkCmdInsertDebugUtilsLabelEXT can be used as defined below.

A command buffer debug label region can be opened by calling:

void vkCmdBeginDebugUtilsLabelEXT(
    VkCommandBuffer                             commandBuffer,
    const VkDebugUtilsLabelEXT*           =
      pLabelInfo);
  • commandBuffer is the command buffer into which the command = is recorded.

  • pLabelInfo is a pointer to an instance of the VkDebugUtilsLabelEXT structure specifying the par= ameters of the label region to open.

Valid Usage (Implicit)
  • = commandBuffer must be a val= id VkCommandBuffer handle

  • pLabelInfo must be a valid poi= nter to a valid VkDebugUtilsLabelEXT structure

  • = commandBuffer must be in th= e recording state

  • T= he VkCommandPool that commandBuffer was allocated= from must support graphics, or compute o= perations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

A command buffer label region can be closed by calling:

void vkCmdEndDebugUtilsLabelEXT(
    VkCommandBuffer                             commandBuffer);
  • commandBuffer is the command buffer into which the command = is recorded.

An application may open a debug label = region in one command buffer and close it in another, or otherwise split debug label regions across multiple command buffers or multiple queue submissions. When viewed from the linear series of submissions to a single queue, the calls to vkCmdBeginDebugUtilsLabelEXT and vkCmdEndDebugUtilsLabelEXT must be matched and balanced.

Valid Usage
  • There must be an outstanding vkCmdB= eginDebugUtilsLabelEXT command prior to the vkCmdEndDebugUtilsLabelEXT on the queue that commandBuffer is submitted to

  • If commandBuffer is a secondary command buffer, there must be an outstanding vkCmdBeginDebugUtilsLabelEXT command recorded to commandBuffer that has not previously been ended by a call to vkCmdEndDebugUtilsLabelEXT.

Valid Usage (Implicit)
  • <= code>commandBuffer must be a valid= VkCommandBuffer handle

  • <= code>commandBuffer must be in the = recording state

  • The= VkCommandPool that commandBuffer was allocated f= rom must support graphics, or compute ope= rations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

A single debug label can be inserted into a command buffer by calling:

void vkCmdInsertDebugUtilsLabelEXT(
    VkCommandBuffer                             commandBuffer,
    const VkDebugUtilsLabelEXT*           =
      pLabelInfo);
  • commandBuffer is the command buffer into which the command = is recorded.

  • pInfo is a pointer to an instance of the VkDebugUtilsLabelEXT structure specifying the par= ameters of the label to insert.

Valid Usage (Implicit)
Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

33.1.4. Debug Messengers

Vulkan allows an application to register multiple callbacks with any Vul= kan component wishing to report debug information. Some callbacks may log the information to a file, others may cause a debug break point or other application defined behavior. A primary producer of callback messages are the validation layers. An application can register callbacks eve= n when no validation layers are enabled, but they will only be called for the Vulkan loader and, if implemented, other layer and driver events.

A VkDebugUtilsMessengerEXT is a messenger object which hand= les passing along debug messages to a provided debug callback.

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDebugUtilsMessengerEXT)

The debug messenger will provide detailed feedback on the application=E2= =80=99s use of Vulkan when events of interest occur. When an event of interest does occur, the debug messenger will submit a debug message to the debug callback that was provided during its creation. Additionally, the debug messenger is responsible with filtering out debug messages that the callback is not interested in and will only provide desired debug messages.

A debug messenger triggers a debug callback with a debug message when an event of interest occurs. To create a debug messenger which will trigger a debug callback, call:

VkResult vkCreateD=
ebugUtilsMessengerEXT(
    VkInstance                                  instance,
    const VkDebugUtilsMessengerCreateInfoE=
XT*   pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDebugUtilsMessengerEXT*                   pMessenger);
  • instance the instance the messenger will be used with.

  • pCreateInfo points to a VkDebugUtilsMessengerCreateInfoEXT structure which contains the callback pointer as well as defines the conditions under which this messenger will trigger the callback.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pMessenger is a pointer to record the VkDebugUtilsMessengerEXT object created.

Valid Usage (Implicit)
  • instance must be a valid VkInstance handle

  • = pCreateInfo must be a valid= pointer to a valid VkDebugUtilsMessengerCreateInfoEXT structu= re

  • = If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • = pMessenger must be a valid p= ointer to a VkDebugUtilsMessengerEXT handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

The definition of VkDebugUtilsMessengerCreateInfoEXT is:

typedef struct VkDebugUtilsMess=
engerCreateInfoEXT {
    VkStructureType                         sType;
    const void*                             pNext;
    VkDebugUtilsMessengerCreateFlagsEXT     flags;
    VkDebugUtilsMessageSeverityFlagsEXT     messageSeverity;
    VkDebugUtilsMessageTypeFlagsEXT         messageType;
    PFN_vkDebugUtilsMessengerCallbackEXT    pfnUserCallback;
    void*                                 =
  pUserData;
} VkDebugUtilsMessengerCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is 0 and reserved for future use.

  • messageSeverity is a bitmask of VkDebugUtilsMessageSeverityFlagBits= EXT specifying which severity of event(s) will cause this callback to be called.

  • messageTypes is a bitmask of VkDebugUtilsMessageTypeFlagBitsEXT = specifying which type of event(s) will cause this callback to be called.

  • pfnUserCallback is the application callback function to cal= l.

  • pUserData is user data to be passed to the callback.

For each VkDebugUtilsMessengerEXT that is created the VkDebugUtilsMessengerCreateInfoEXT::messageSeverity and VkDebugUtilsMessengerCreateInfoEXT::messageTypes = determine when that VkDebugUtilsMessengerCreateInfoEXT::pfnUserCallback= is called. The process to determine if the user=E2=80=99s pfnUserCallback is triggered= when an event occurs is as follows:

  1. The implementation will perform a bitwise AND of the event=E2=80=99s VkDebugUtilsMessageSeverityFlagBits= EXT with the messageSeverity provided during creation of the VkDebugUtilsMessengerEXT object.

    1. If the value is 0, the message is skipped.

  2. The implementation will perform bitwise AND of the event=E2=80=99s VkDebugUtilsMessageTypeFlagBitsEXT = with the messageType provided during the creation of the VkDebugUtilsM= essengerEXT object.

    1. If the value is 0, the message is skipped.

  3. The callback will trigger a debug message for the current event

The callback will come directly from the component that detected the eve= nt, unless some other layer intercepts the calls for its own purposes (filter them in a different way, log to a system error log, etc.).

An application can receive multiple ca= llbacks if multiple VkDebugUtilsMessengerEXT objects are created. A callback will always be executed in the same thread as the originating Vulkan call.

A callback can be called from multiple= threads simultaneously (if the application is making Vulkan calls from multiple threads).

Valid Usage
Valid Usage (Implicit)

Bits which can be set in VkDebugUtilsMessengerCreateInfoEXT:= :messageSeverity, specifying event severities which cause a debug messenger to call the callback, are:

typedef enum VkDebugUtilsMessag=
eSeverityFlagBitsEXT {
    VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT =3D 0x00000001,
    VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT =3D 0x=
00000010,
    VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT =3D 0x00000100,
    VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT =3D 0=
x00001000,
} VkDebugUtilsMessageSeverityFlagBitsEXT;
  • VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT specifies t= he most verbose output indicating all diagnostic messages from the Vulkan loader, layers, and drivers should be captured.

  • VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT specifies an informational message such as resource details that may be handy when debugging an application.

  • VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT specifies u= se of Vulkan that may expose an app bug. Such cases may not be immediately harmful, such as a fragment shader outputting to a location with no attachment. Other cases may point to behavior that is= almost certainly bad when unintended such as using an image whose memory has not been filled. In general if you see a warning but you know that the behavior is intended/desired, then simply ignore the warning.

  • VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT specifies tha= t an error that may cause undefined results, including an application crash.

Note

The values of VkDebugUtilsMessageSeverityFlagBitsEXT are so= rted based on severity. The higher the flag value, the more severe the message. This allows for simple boolean operation comparisons when looking at VkDebugUtilsMessageSeverityFlagBitsEXT values.

For example:

    if (messageSeverity >=3D VK_DEBUG_UTILS_MESSAGE_SEVERIT=
Y_WARNING_BIT_EXT) {
        // Do something for warnings and errors
    }

In addition, space has been left between the enums to allow for later addition of new severities in between the existing values.

Bits which can be set in VkDebugUtilsMessengerCreateInfoEXT:= :messageTypes, specifying event types which cause a debug messenger to call the callback, are:

typedef enum VkDebugUtilsMessag=
eTypeFlagBitsEXT {
    VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT =3D 0x0=
0000001,
    VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT =3D =
0x00000002,
    VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT =3D 0x00000004,
} VkDebugUtilsMessageTypeFlagBitsEXT;
  • VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT specifies that = some general event has occurred. This is typically a non-specification, non-performance event.

  • VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT specifies th= at something has occurred during validation against the Vulkan specification that may indicate invalid behavior.

  • VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT specifies a potentially non-optimal use of Vulkan, e.g. using vkCmdClearColorImage when setting VkAttachmentDescription::loadOp t= o VK_ATTACHMENT_LOAD_OP_CLEAR would have worked.

The prototype for the VkDebugUtilsMessengerCreateInfoEXT:= :pfnUserCallback function implemented by the application is:

typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallback=
EXT)(
    VkDebugUtilsMessageSeverityFlagBitsEXT           messageSeverity,
    VkDebugUtilsMessageTypeFlagsEXT                  messageType,
    const VkDebugUtilsMessengerCallbackDat=
aEXT*      pCallbackData,
    void*                                 =
           pUserData);

The callback must not call vkDestroyDebugUtilsMessengerEXT.

The callback returns a VkBool32, which is interpreted in a layer-specified manner. The application should always return VK_FALSE. The VK_TRUE value is reserved for use in layer development.

The definition of VkDebugUtilsMessengerCallbackDataEXT is:<= /p>

typedef struct VkDebugUtilsMess=
engerCallbackDataEXT {
    VkStructureType                              sType;
    const void*                                  pNext;
    VkDebugUtilsMessengerCallbackDataFlagsEXT    flags;
    const =
char*                                  pMessageIdName;
    int32_t                                      messageIdNumber;
    const =
char*                                  pMessage;
    uint32_t                                     queueLabelCount;
    VkDebugUtilsLabelEXT*                        pQueueLabels;
    uint32_t                                     cmdBufLabelCount;
    VkDebugUtilsLabelEXT*                        pCmdBufLabels;
    uint32_t                                     objectCount;
    VkDebugUtilsObjectNameInfoEXT*               pObjects;
} VkDebugUtilsMessengerCallbackDataEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is 0 and reserved for future use.

  • pMessageIdName is a null-terminated string that identifies = the the particular message ID that is associated with the provided message. If the message corresponds to a validation layer message, then this string may contain the portion of the Vulkan specification that is believed to have been violated.

  • messageIdNumber is the ID number of the triggering message. If the message corresponds to a validation layer message, then this number is related to the internal number associated with the message being triggered.

  • pMessage is a null-terminated string detailing the trigger conditions.

  • queueLabelCount is a count of items contained in the pQueueLabels array.

  • pQueueLabels is NULL or a pointer to an array of VkDebugUtilsLabelEXT active in the current = VkQueue at the time the callback was triggered. Refer to Queue Labels for more information.

  • cmdBufLabelCount is a count of items contained in the pCmdBufLabels array.

  • pCmdBufLabels is NULL or a pointer to an array of VkDebugUtilsLabelEXT active in the current = VkCommandBuffer at the time the callback was triggered. Refer to Command Buffer Labels for more information.

  • objectCount is a count of items contained in the pObj= ects array.

  • pObjects is a pointer to an array of VkDebugUtilsObjectNameInfoEXT objects re= lated to the detected issue. The array is roughly in order or importance, but the 0th element is always guaranteed to be the most important object for this message.

Note

This structure should only be considered valid during the lifetime of th= e triggered callback.

Since adding queue and command buffer labels behaves like pushing and popping onto a stack, the order of both pQueueLabels and pCmdBufLabels is based on the order the labels were defined. The result is that the first label in either pQueueLabels or pCmdBufLabels will be the first defined (and therefore the old= est) while the last label in each list will be the most recent.

Note

pQueueLabels will only be non-NULL if one of the objects in pObjects can be related directly to a defined VkQueue which has had one or more labels associated with it.

Likewise, pCmdBufLabels will only be non-NULL if one of the= objects in pObjects can be related directly to a defined VkCommandB= uffer which has had one or more labels associated with it. Additionally, while command buffer labels allow for beginning and ending across different command buffers, the debug messaging framework cannot guarantee that labels in pCmdBufLables will contain those defi= ned outside of the associated command buffer. This is partially due to the fact that the association of one command buffe= r with another may not have been defined at the time the debug message is triggered.

Valid Usage (Implicit)

There may be times that a user wishes to intentionally submit a debug message. To do this, call:

void vkSubmitDebugUtilsMessageEXT(
    VkInstance                                  instance,
    VkDebugUtilsMessageSeverityFlagBitsEXT      messageSeverity,
    VkDebugUtilsMessageTypeFlagsEXT             messageTypes,
    const VkDebugUtilsMessengerCallbackDat=
aEXT* pCallbackData);

The call will propagate through the layers and generate callback(s) as indicated by the message=E2=80=99s flags. The parameters are passed on to the callback in addition to the pUserData value that was defined at the time the messenger was registered.

Valid Usage (Implicit)

To destroy a VkDebugUtilsMessengerEXT object, call:

void vkDestroyDebugUtilsMessengerEXT(
    VkInstance                                  instance,
    VkDebugUtilsMessengerEXT                    messenger,
    const VkAllocationCallbacks*          =
      pAllocator);
  • instance the instance where the callback was created.

  • messenger the VkDebugUtilsMesseng= erEXT object to destroy. messenger is an externally synchronized object and must not be used on more than one thread at a time. This means that vkDestroyDebugUtilsMessengerEXT must not be called when a callback is active.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • If VkAllocationCallbacks were provided when messenger was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when messenger= was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • <= code>instance must be a valid VkInstance handle

  • = messenger must be a valid VkDebugUtilsMessengerEXT handle

  • = If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • messenger must have been create= d, allocated, or retrieved from instance

Host Synchronization
  • Host access to messenger must be externally synchronized

33.2. Debug Markers

Debug markers provide a flexible way for debugging and validation layers= to receive annotation and debug information.

The Object Annotation section describes= how to associate a name or binary data with a Vulkan object.

The Command Buffer Markers section describes how to associate logical elements of the scene with commands in the command buffer.

33.2.1. Object Annotation

The commands in this section allow application developers to associate user-defined information with Vulkan objects at will.

An object can be given a user-friendly name by calling:

VkResult vkDebugMa=
rkerSetObjectNameEXT(
    VkDevice                                    device,
    const VkDebugMarkerObjectNameInfoEXT* =
      pNameInfo);
  • device is the device that created the object.

  • pNameInfo is a pointer to an instance of the VkDebugMarkerObjectNameInfoEXT structur= e specifying the parameters of the name to set on the object.

Valid Usage (Implicit)
  • device must be a valid VkDe= vice handle

  • pNameInfo must be a valid poin= ter to a valid VkDebugMarkerObjectNameInfoEXT structure

Host Synchronization
  • Host access to pNameInfo.object mu= st be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDebugMarkerObjectNameInfoEXT structure is defined as:=

typedef struct VkDebugMarkerObj=
ectNameInfoEXT {
    VkStructureType               sType;
    const void*                   pNext;
    VkDebugReportObjectTypeEXT    objectType;
    uint64_t                      object;
    const =
char*                   pObjectName;
} VkDebugMarkerObjectNameInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • objectType is a VkDebugReportOb= jectTypeEXT specifying the type of the object to be named.

  • object is the object to be named.

  • pObjectName is a null-terminated UTF-8 string specifying th= e name to apply to object.

Applications may change the name assoc= iated with an object simply by calling vkDebugMarkerSetObjectNameEXT again with a new string. To remove a previously set name, pObjectName should be set to an empty string.

Valid Usage
Valid Usage (Implicit)
  • sTy= pe must be VK_STRUCTURE_TYPE= _DEBUG_MARKER_OBJECT_NAME_INFO_EXT

  • pNe= xt must be NULL

  • = objectType must be a valid <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#V= kDebugReportObjectTypeEXT">VkDebugReportObjectTypeEXT value

  • = pObjectName must be a null-= terminated UTF-8 string

In addition to setting a name for an object, debugging and validation la= yers may have uses for additional binary data on a per-object basis that has no other place in the Vulkan API. For example, a VkShaderModule could have additional debugging = data attached to it to aid in offline shader tracing. To attach data to an object, call:

VkResult vkDebugMa=
rkerSetObjectTagEXT(
    VkDevice                                    device,
    const VkDebugMarkerObjectTagInfoEXT*  =
      pTagInfo);
  • device is the device that created the object.

  • pTagInfo is a pointer to an instance of the VkDebugMarkerObjectTagInfoEXT structure = specifying the parameters of the tag to attach to the object.

Valid Usage (Implicit)
  • = device must be a valid VkDev= ice handle

  • pTagInfo must be a valid pointer= to a valid VkDebugMarkerObjectTagInfoEXT structure

Host Synchronization
  • Host access to pTagInfo.object mus= t be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDebugMarkerObjectTagInfoEXT structure is defined as:<= /p>

typedef struct VkDebugMarkerObj=
ectTagInfoEXT {
    VkStructureType               sType;
    const void*                   pNext;
    VkDebugReportObjectTypeEXT    objectType;
    uint64_t                      object;
    uint64_t                      tagName;
    size_t                        tagSize;
    const void*                   pTag;
} VkDebugMarkerObjectTagInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • objectType is a VkDebugReportOb= jectTypeEXT specifying the type of the object to be named.

  • object is the object to be tagged.

  • tagName is a numerical identifier of the tag.

  • tagSize is the number of bytes of data to attach to the obj= ect.

  • pTag is an array of tagSize bytes containing t= he data to be associated with the object.

The tagName parameter gives a name or identifier to the typ= e of data being tagged. This can be used by debugging layers to easily filter for only data that ca= n be used by that implementation.

Valid Usage
Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= DEBUG_MARKER_OBJECT_TAG_INFO_EXT

  • pNex= t must be NULL

  • <= code>objectType must be a valid VkDebugReportObjectTypeEXT value

  • p= Tag must be a valid pointer to an = array of tagSize bytes

  • tagSize must be greater than <= code>0

33.2.2. Command Buffer Markers<= /h4>

Typical Vulkan applications will submit many command buffers in each fra= me, with each command buffer containing a large number of individual commands. Being able to logically annotate regions of command buffers that belong together as well as hierarchically subdivide the frame is important to a developer=E2=80=99s ability to navigate the commands viewed holistically.

The marker commands vkCmdDebugMarkerBeginEXT and vkCmdDebugMarkerEndEXT define regions of a series of commands = that are grouped together, and they can be nested to create a hierarchy. The vkCmdDebugMarkerInsertEXT command allows insertion of a si= ngle label within a command buffer.

A marker region can be opened by calling:

void vkCmdDebugMarkerBeginEXT(
    VkCommandBuffer                             commandBuffer,
    const VkDebugMarkerMarkerInfoEXT*     =
      pMarkerInfo);
  • commandBuffer is the command buffer into which the command = is recorded.

  • pMarkerInfo is a pointer to an instance of the VkDebugMarkerMarkerInfoEXT structure specif= ying the parameters of the marker region to open.

Valid Usage (Implicit)
  • commandBuffer must be a valid <= code>VkCommandBuffer handle

  • pMarkerInfo must be a valid point= er to a valid VkDebugMarkerMarkerInfoEXT structure

  • commandBuffer must be in the recording state

  • The <= code>VkCommandPool that commandBuffer was allocated fro= m must support graphics, or compute opera= tions

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

The VkDebugMarkerMarkerInfoEXT structure is defined as:

typedef struct VkDebugMarkerMar=
kerInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    const =
char*        pMarkerName;
    float              color[4];
} VkDebugMarkerMarkerInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • pMarkerName is a pointer to a null-terminated UTF-8 string = that contains the name of the marker.

  • color is an optional RGBA= color value that can be associated with the marker. A particular implementation may choose to= ignore this color value. The values contain RGBA values in order, in the range 0.0 to 1.0. If all elements in color are set to 0.0 then it is ignored.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEB= UG_MARKER_MARKER_INFO_EXT

  • pNext must be NULL

  • pMarkerName must be a null-term= inated UTF-8 string

A marker region can be closed by calling:

void vkCmdDebugMarkerEndEXT(
    VkCommandBuffer                             commandBuffer);
  • commandBuffer is the command buffer into which the command = is recorded.

An application may open a marker regio= n in one command buffer and close it in another, or otherwise split marker regions across multiple command buffers or multiple queue submissions. When viewed from the linear series of submissions to a single queue, the calls to vkCmdDebugMarkerBeginEXT and vkCmdDebugMarkerEn= dEXT must be matched and balanced.

Valid Usage
  • There must be an outstanding vkCmdDebugMarkerBeginEXT command prior to the vkCmdDebugMarkerEndEXT on the queue that commandBuffer is submitted to

  • If commandBuffer is a secondary command buffer, there must be an outstanding vkCmdDebugMarkerBeginEXT command = recorded to commandBuffer that has not previously been ended by a call to vkCmdDebugMarkerEndEXT.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from = must support graphics, or compute operati= ons

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

A single marker label can be inserted into a command buffer by calling:<= /p>

void vkCmdDebugMarkerInsertEXT(
    VkCommandBuffer                             commandBuffer,
    const VkDebugMarkerMarkerInfoEXT*     =
      pMarkerInfo);
  • commandBuffer is the command buffer into which the command = is recorded.

  • pMarkerInfo is a pointer to an instance of the VkDebugMarkerMarkerInfoEXT structure specif= ying the parameters of the marker to insert.

Valid Usage (Implicit)
  • commandBuffer must be a valid = VkCommandBuffer handle

  • pMarkerInfo must be a valid poin= ter to a valid VkDebugMarkerMarkerInfoEXT structure

  • commandBuffer must be in the <= a href=3D"https://vulkan.lunarg.com/doc/view/1.1.82.1/windows/vkspec.html#c= ommandbuffers-lifecycle">recording state

  • The = VkCommandPool that commandBuffer was allocated fr= om must support graphics, or compute oper= ations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute

33.3. Debug Report Callbacks

Debug report callbacks are represented by VkDebugReportCallbackEXT= handles:

VK_DEFINE_NON_DISP=
ATCHABLE_HANDLE(VkDebugReportCallbackEXT)

Debug report callbacks give more detailed feedback on the application=E2= =80=99s use of Vulkan when events of interest occur.

To register a debug report callback, an application uses vkCreateDebugReportCallbackEXT.

VkResult vkCreateD=
ebugReportCallbackEXT(
    VkInstance                                  instance,
    const VkDebugReportCallbackCreateInfoE=
XT*   pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDebugReportCallbackEXT*                   pCallback);
  • instance the instance the callback will be logged on.

  • pCreateInfo points to a VkDebugReportCallbackCreateInfoEXT structure which defines the conditions under which this callback will be called.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pCallback is a pointer to record the VkDebugReportCallbackEXT object created.

Valid Usage (Implicit)
  • instance must be a valid VkInstance handle

  • = pCreateInfo must be a valid= pointer to a valid VkDebugReportCallbackCreateInfoEXT structu= re

  • = If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • <= code>pCallback must be a valid poi= nter to a VkDebugReportCallbackEXT handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

The definition of VkDebugReportCallb= ackCreateInfoEXT is:

typedef struct VkDebugReportCal=
lbackCreateInfoEXT {
    VkStructureType                 sType;
    const void*                     pNext;
    VkDebugReportFlagsEXT           flags;
    PFN_vkDebugReportCallbackEXT    pfnCallback;
    void*                           pUserD=
ata;
} VkDebugReportCallbackCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask of VkDebugRepo= rtFlagBitsEXT specifying which event(s) will cause this callback to be called.

  • pfnCallback is the application callback function to call.

  • pUserData is user data to be passed to the callback.

For each VkDebugReportCallbackEXT that is created the VkDebugReportCallbackCreateInfoEXT::flags determi= ne when that VkDebugReportCallbackCreateInfoEXT::pfnCallback i= s called. When an event happens, the implementation will do a bitwise AND of the event=E2=80=99s VkDebugReportFlagBitsEXT flag= s to each VkDebugReportCallbackEXT object=E2=80=99s flags. For each non-zero result the corresponding callback will be called. The callback will come directly from the component that detected the event, unless some other layer intercepts the calls for its own purposes (filter them in a different way, log to a system error log, etc.).

An application may receive multiple ca= llbacks if multiple VkDebugReportCallbackEXT objects were created. A callback will always be executed in the same thread as the originating Vulkan call.

A callback may be called from multiple threads simultaneously (if the application is making Vulkan calls from multiple threads).

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_= TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT

  • <= code>flags must be a valid combina= tion of VkDebugReportFlagBitsEXT values

Bits which can be set in VkDebugReportCallbackCreateInfoEXT:= :flags, specifying events which cause a debug report, are:

typedef enum VkDebugReportFlagB=
itsEXT {
    VK_DEBUG_REPORT_INFORMATION_BIT_EXT =3D 0x00000001<=
/span>,
    VK_DEBUG_REPORT_WARNING_BIT_EXT =3D 0x00000002,
    VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT =3D 0x0=
0000004,
    VK_DEBUG_REPORT_ERROR_BIT_EXT =3D 0x00000008=
,
    VK_DEBUG_REPORT_DEBUG_BIT_EXT =3D 0x00000010=
,
} VkDebugReportFlagBitsEXT;
  • VK_DEBUG_REPORT_ERROR_BIT_EXT specifies that an error that = may cause undefined results, including an application crash.

  • VK_DEBUG_REPORT_WARNING_BIT_EXT specifies use of Vulkan tha= t may expose an app bug. Such cases may not be immediately harmful, such as a fragment shader outputting to a location with no attachment. Other cases may point to behavior that is= almost certainly bad when unintended such as using an image whose memory has not been filled. In general if you see a warning but you know that the behavior is intended/desired, then simply ignore the warning.

  • VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT specifies a potentially non-optimal use of Vulkan, e.g. using vkCmdClearColorImage when setting VkAttachmentDescription::loadOp t= o VK_ATTACHMENT_LOAD_OP_CLEAR would have worked.

  • VK_DEBUG_REPORT_INFORMATION_BIT_EXT specifies an informatio= nal message such as resource details that may be handy when debugging an application.

  • VK_DEBUG_REPORT_DEBUG_BIT_EXT specifies diagnostic informat= ion from the implementation and layers.

typedef VkFlags VkDebugReportFlagsEXT;

VkDebugReportFlagsEXT is a bitmask type for setting a mask = of zero or more VkDebugReportFlagBitsEXT.

The prototype for the VkDebugReportCallbackCreateInfoEXT:= :pfnCallback function implemented by the application is:

typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)(
    VkDebugReportFlagsEXT                       flags,
    VkDebugReportObjectTypeEXT                  objectType,
    uint64_t                                    object,
    size_t                                      location,
    int32_t                                     messageCode,
    const =
char*                                 pLayerPrefix,
    const =
char*                                 pMessage,
    void*                                 =
      pUserData);
  • flags specifies the VkDebugReport= FlagBitsEXT that triggered this callback.

  • objectType is a VkDebugReportOb= jectTypeEXT value specifying the type of object being used or created at the time the event was triggered.

  • object is the object where the issue was detected. If objectType is VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT= , object is undefined.

  • location is a component (layer, driver, loader) defined val= ue that specifies the location of the trigger. This is an optional value.

  • messageCode is a layer-defined value indicating what test triggered this callback.

  • pLayerPrefix is a null-terminated string that is an abbrevi= ation of the name of the component making the callback. pLayerPrefix is only valid for the duration of the callback.

  • pMessage is a null-terminated string detailing the trigger conditions. pMessage is only valid for the duration of the callback.

  • pUserData is the user data given when the VkDebugReportCallbackEXT was created.

The callback must not call vkDes= troyDebugReportCallbackEXT.

The callback returns a VkBool32, which is interpreted in a layer-specified manner. The application should always return VK_FALSE. The VK_TRUE value is reserved for use in layer development.

object must be a Vulkan o= bject or VK_NULL_HANDLE. If objectType is not VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN= _EXT and object is not VK_NULL_HANDLE, object= must be a Vulkan object of the corresponding type associated with objectType as= defined in VkDebugReportObjectTypeEXT and Vulkan Handle = Relationship.

Possible values passed to the objectType parameter of the c= allback function specified by VkDebugReportCallbackCreateInfoEXT:= :pfnCallback, specifying the type of object handle being reported, are:

typedef enum VkDebugReportObjec=
tTypeEXT {
    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT =3D 0,
    VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT =3D 1<=
/span>,
    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT =3D 2,
    VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT =3D 3,
    VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT =3D 4,
    VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT =3D 5=
,
    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT =3D 6,
    VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT =3D 7,
    VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT =3D 8,
    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT =3D 9,
    VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT =3D 10,
    VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT =3D 11,
    VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT =3D =
12,
    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT =3D 13,
    VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT =3D =
14,
    VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT =3D 15,
    VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT =3D 16,
    VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT =3D 17,
    VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT =3D 18,
    VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT =3D 19=
,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT =3D 20,
    VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT =3D 21<=
/span>,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT =3D 22,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT =3D 23,
    VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT =3D 24,
    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT =3D 25,
    VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT =3D 26,
    VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT =3D 27,
    VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT =3D 28,
    VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT =3D 29,
    VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT =3D 30,
    VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT =3D 31,
    VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT =3D 32,
    VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT =3D 33,
    VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT =3D 1000156000,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT =3D 1000085000,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT =3D VK_D=
EBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT,
    VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT =3D VK_DEB=
UG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT,
} VkDebugReportObjectTypeEXT;
Table 74. VkDebugReportObjectTypeEXT and Vulkan Ha= ndle Relationship
VkDebugReportObjectTypeEXT Vulkan Handle Type

VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT

Unk= nown/Undefined Handle

VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT

VkInstance

VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT

VkPhysicalDevice

VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT

VkDevice

VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT

VkQueue

VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT

VkSemaphore

VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT

VkCommandBuffer

VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT

VkFence

VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT

VkDeviceMemory

VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT

VkBuffer

VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT

VkImage

VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT

VkEvent

VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT

VkQueryPool

VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT

VkBufferView

VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT

VkImageView

VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT

VkShaderModule

VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT

VkPipelineCache

VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT

VkPipelineLayout

VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT

VkRenderPass

VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT

VkPipeline

VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT

VkDescriptorSetLayout

VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT

VkSampler

VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT

VkDescriptorPool

VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT

VkDescriptorSet

VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT

VkFramebuffer

VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT

VkCommandPool

VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT

VkSurfaceKHR

VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT

VkSwapchainKHR

VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT

VkDebugReportCallbackEXT

VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT

VkDisplayKHR

VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT

VkDisplayModeKHR

VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT

VkObjectTableNVX

VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT

<= /td>

VkIndirectCommandsLayoutNVX

VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT

VkDescriptorUpdateTemplate

Note

The primary expected use of VK_ERROR_VALIDATION_FAILED_EXT = is for validation layer testing. It is not expected that an application would see this error code during normal use of the validation layers.

To inject its own messages into the debug stream, call:

void vkDebugReportMessageEXT(
    VkInstance                                  instance,
    VkDebugReportFlagsEXT                       flags,
    VkDebugReportObjectTypeEXT                  objectType,
    uint64_t                                    object,
    size_t                                      location,
    int32_t                                     messageCode,
    const =
char*                                 pLayerPrefix,
    const =
char*                                 pMessage);
  • instance is the debug stream=E2=80=99s VkInstan= ce.

  • flags specifies the VkDebugReport= FlagBitsEXT classification of this event/message.

  • objectType is a VkDebugReportOb= jectTypeEXT specifying the type of object being used or created at the time the event was triggered.

  • object this is the object where the issue was detected. object can be VK_NULL_= HANDLE if there is no object associated with the event.

  • location is an application defined value.

  • messageCode is an application defined value.

  • pLayerPrefix is the abbreviation of the component making th= is event/message.

  • pMessage is a null-terminated string detailing the trigger conditions.

The call will propagate through the layers and generate callback(s) as indicated by the message=E2=80=99s flags. The parameters are passed on to the callback in addition to the pUserData value that was defined at the time the callback was registered.

Valid Usage
  • object must be a Vulkan obje= ct or VK_NULL_HANDLE

  • If objectType is not VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN= _EXT and object is not VK_NULL_HANDLE, object must be a Vulkan object of the corresponding type associated with objectType as defined in VkDebugReportObjectTypeEXT and Vul= kan Handle Relationship.

Valid Usage (Implicit)
  • ins= tance must be a valid VkInst= ance handle

  • flags<= /code> must be a valid combination of VkDebugReportFlagBitsEXT values

  • = flags must not be 0

  • o= bjectType must be a valid VkDebugReportObjectTypeEXT value

  • pLayerPrefix must be a null-termi= nated UTF-8 string

  • pMe= ssage must be a null-terminated UT= F-8 string

To destroy a VkDebugReportCallbackEXT object, call:

void vkDestroyDebugReportCallbackEXT(
    VkInstance                                  instance,
    VkDebugReportCallbackEXT                    callback,
    const VkAllocationCallbacks*          =
      pAllocator);
  • instance the instance where the callback was created.

  • callback the VkDebugReportCallbac= kEXT object to destroy. callback is an externally synchronized object and must not be used on more than one thread at a time. This means that vkDestroyDebugReportCallbackEXT must not be called when a callback is active.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

Valid Usage
  • If VkAllocationCallbacks were provided when callback was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when callback<= /code> was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • <= code>instance must be a valid VkInstance handle

  • <= code>callback must be a valid VkDebugReportCallbackEXT handle

  • = If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • callback must have been created,= allocated, or retrieved from instance

Host Synchronization
  • Host access to callback must be externally synchronized

33.4. Device Loss Debugging

33.4.1. Device Diagnostic Checkpo= ints

Device execution progress can be track= ed for the purposes of debugging a device loss by annotating the command stream with application-defined diagnostic checkpoints.

Each diagnostic checkpoint command is executed at two pipeline stages: VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, and VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT. If the device is lost, the application can call vkGetQueueCheckpointDataNV to retrieve chec= kpoint data associated with both pipeline stages, indicating the range of diagnostic checkpoints that are currently in the execution pipeline on the device.

Device diagnostic checkpoints are inserted into the command stream by calling vkCmdSetCheckpointNV.

void vkCmdSetCheckpointNV(
    VkCommandBuffer                             commandBuffer,
    const void*                                 pCheckpointMarker);
  • commandBuffer is the command buffer that will receive the m= arker

  • pCheckpointMarker is an opaque application-provided value t= hat will be associated with the checkpoint.

Valid Usage (Implicit)
  • c= ommandBuffer must be a valid VkCommandBuffer handle

  • c= ommandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, compute, or transfer= operations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be external= ly synchronized

Command Properties
Comma= nd Buffer Levels Rende= r Pass Scope Supported = Queue Types Pipeline Type

Pri= mary
Secondary

Bot= h

Gra= phics
Compute
Transfer

Note that pCheckpointMarker is treated as an opaque value. It does not need to be a valid pointer and will not be dereferenced by the implementation.

If the device encounters an error during execution, the implementation w= ill return a VK_ERROR_DEVICE_LOST error to the application at a ce= rtain point during host execution. When this happens, the application can ca= ll vkGetQueueCheckpointDataNV to retrieve info= rmation on the most recent diagnostic checkpoints that were executed by the device.

void vkGetQueueCheckpointDataNV(
    VkQueue                                     queue,
    uint32_t*                                   pCheckpointDataCount,
    VkCheckpointDataNV*                         pCheckpointData);
  • queue is the VkQueue object the caller would l= ike to retrieve checkpoint data for

  • pCheckpointDataCount is a pointer to an integer related to = the number of checkpoint markers available or queried, as described below.

  • pCheckpointData is either NULL or a pointer to= an array of VkCheckpointDataNV structures.

If pCheckpointData is NULL, then the number of= checkpoint markers available is returned in pCheckpointDataCount.

Otherwise, pCheckpointDataCount mu= st point to a variable set by the user to the number of elements in the pCheckpointData array, a= nd on return the variable is overwritten with the number of structures actually written to pCheckpointData.

If pCheckpointDataCount is less than the number of checkpoi= nt markers available, at most pCheckpointDataCount structures will be wri= tten.

Valid Usage
  • The device that queue belongs to must= be in the lost state

Valid Usage (Implicit)
  • que= ue must be a valid VkQueue handle

  • pCheckpointDataCount must be a valid pointer to a uint32_t value

  • = If the value referenced by pCheckpointDataCount is not = 0, and pCheckpointData is not NULL, = pCheckpointData must be a valid po= inter to an array of pCheckpointDataCount VkCheckpointDa= taNV structures

The VkCheckpointDataNV structure is defined as:<= /p>

typedef struct VkCheckpointData=
NV {
    VkStructureType            sType;
    void*                      pNext;
    VkPipelineStageFlagBits    stage;
    void*                      pCheckpoint=
Marker;
} VkCheckpointDataNV;
  • sType is the type of this structure

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • stage indicates which pipeline stage the checkpoint marker = data refers to.

  • pCheckpointMarker contains the value of the last checkpoint= marker executed in the stage that stage refers to.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_CHECKPOINT_= DATA_NV

  • pNext must be NULL

Note that the stages at which a checkpoint marker can be executed are implementation-defined and can be queried= by calling vkGetPhysicalDeviceQueueFamilyPr= operties2.

Appendix A: Vulkan Environment for SPIR-V

Shaders for Vulkan are defined by the Khronos SPIR-V Specification as well as the Khronos SPIR-V Extended Instructions for GLSL Specification. This appendix defines additional SPIR-V requirements applying to Vulkan shaders.

Capabilities

Implementations must support the follo= wing capability operands declared by OpCapability:

If the implementation supports any of the optio= nal features described in the Features chapter, then the capability operand(s) corresponding to that feature must also b= e supported.

Table 75. List of optiona= l SPIR-V Capabilities and corresponding feature or extension names=
SPIR-V OpCapability Vulkan feature or extension= name

Geometry

geometryShader

Tessellation

tessellationShader

Float64

shaderFloat64

Int64

shaderInt64

Int16

shaderInt16

TessellationPointSize

shaderTessellationAn= dGeometryPointSize

GeometryPointSize

shaderTessellationAn= dGeometryPointSize

ImageGatherExtended

shaderImageGatherExtended

=

StorageImageMultisample

shaderStorageImageMultisample=

UniformBufferArrayDynamicIndexing

shaderUniformBuffer= ArrayDynamicIndexing

SampledImageArrayDynamicIndexing

shaderSampledImageAr= rayDynamicIndexing

StorageBufferArrayDynamicIndexing

shaderStorageBuffer= ArrayDynamicIndexing

StorageImageArrayDynamicIndexing

shaderStorageImageAr= rayDynamicIndexing

ClipDistance

shaderClipDistance

CullDistance

shaderCullDistance

ImageCubeArray

imageCubeArray

SampleRateShading

sampleRateShading

SparseResidency

shaderResourceResidency

MinLod

shaderResourceMinLod

SampledCubeArray

imageCubeArray

ImageMSArray

shaderStorageImageMultisample=

StorageImageExtendedFormats

shaderStorageImageExtende= dFormats

InterpolationFunction

sampleRateShading

StorageImageReadWithoutFormat

shaderStorageImageReadW= ithoutFormat

StorageImageWriteWithoutFormat

shaderStorageImageWrit= eWithoutFormat

MultiViewport

multiViewport

DrawParameters

VK_KHR_shader_draw_parameters or shaderDrawParameters

VariablePointersStorageBuffer

variablePointersStorageBuffer=

VariablePointers

variablePointers

StencilExportEXT

VK_EXT_shader_stencil_export

SubgroupBallotKHR

VK_EXT_shader_subgroup_ballot

SubgroupVoteKHR

VK_EXT_shader_subgroup_vote

ImageReadWriteLodAMD

VK_AMD_shader_image_load_store_lod

ImageGatherBiasLodAMD

VK_AMD_texture_gather_bias_lod

FragmentMaskAMD

VK_AMD_shader_fragment_mask

SampleMaskOverrideCoverageNV

VK_NV_sample_mask_override_coverage=

GeometryShaderPassthroughNV

VK_NV_geometry_shader_passthrough=

<= /td>

ShaderViewportIndexLayerEXT

VK_EXT_shader_viewport_index_layer

ShaderViewportIndexLayerNV

VK_NV_viewport_array2

ShaderViewportMaskNV

VK_NV_viewport_array2

PerViewAttributesNV

VK_NVX_multiview_per_view_attribut= es

StorageBuffer16BitAccess

StorageBuffer16BitAccess

UniformAndStorageBuffer16BitAccess

UniformAndStorageBuffer1= 6BitAccess

StoragePushConstant16

storagePushConstant16

StorageInputOutput16

storageInputOutput16

GroupNonUniform

VK_SUBGROUP_FEATURE_BASIC_BIT

GroupNonUniformVote

VK_SUBGROUP_FEATURE_VOTE_BIT

GroupNonUniformArithmetic

VK_SUBGROUP_FEATURE_ARITHMETIC_BIT<= /p>

GroupNonUniformBallot

VK_SUBGROUP_FEATURE_BALLOT_BIT

GroupNonUniformShuffle

VK_SUBGROUP_FEATURE_SHUFFLE_BIT

GroupNonUniformShuffleRelative

VK_SUBGROUP_FEATURE_SHUFFLE_RELAT= IVE_BIT

GroupNonUniformClustered

VK_SUBGROUP_FEATURE_CLUSTERED_BIT

GroupNonUniformQuad

VK_SUBGROUP_FEATURE_QUAD_BIT

GroupNonUniformPartitionedNV

VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV=

SampleMaskPostDepthCoverage

VK_EXT_post_depth_coverage

ShaderNonUniformEXT

VK_EXT_descriptor_indexing

RuntimeDescriptorArrayEXT

runtimeDescriptorArray

InputAttachmentArrayDynamicIndexingEXT

shaderInputAttach= mentArrayDynamicIndexing

UniformTexelBufferArrayDynamicIndexingEXT

shaderUniformT= exelBufferArrayDynamicIndexing

StorageTexelBufferArrayDynamicIndexingEXT

shaderStorageT= exelBufferArrayDynamicIndexing

UniformBufferArrayNonUniformIndexingEXT

shaderUniformBuf= ferArrayNonUniformIndexing

SampledImageArrayNonUniformIndexingEXT

shaderSampledImag= eArrayNonUniformIndexing

StorageBufferArrayNonUniformIndexingEXT

shaderStorageBuf= ferArrayNonUniformIndexing

StorageImageArrayNonUniformIndexingEXT

shaderStorageImag= eArrayNonUniformIndexing

InputAttachmentArrayNonUniformIndexingEXT

shaderInputAtt= achmentArrayNonUniformIndexing

UniformTexelBufferArrayNonUniformIndexingEXT

shaderUnifo= rmTexelBufferArrayNonUniformIndexing

StorageTexelBufferArrayNonUniformIndexingEXT

shaderStora= geTexelBufferArrayNonUniformIndexing

Float16

VK_AMD_gpu_shader_half_float

StorageBuffer8BitAccess

StorageBuffer8BitAccess

UniformAndStorageBuffer8BitAccess

UniformAndStorageBuffer8B= itAccess

StoragePushConstant8

StoragePushConstant8

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_KHR_variable_pointers SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_shader_explicit_vertex_parameter SPIR-V exten= sion.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_gcn_shader SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_gpu_shader_half_float SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_gpu_shader_int16 SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_shader_ballot SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_shader_fragment_mask SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_shader_image_load_store_lod SPIR-V extension.=

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_shader_trinary_minmax SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_AMD_texture_gather_bias_lod SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_KHR_shader_draw_parameters SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_KHR_8bit_storage SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_KHR_16bit_storage SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_KHR_storage_buffer_storage_clas= s SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_KHR_post_depth_coverage SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_EXT_shader_stencil_export SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_KHR_shader_ballot SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_KHR_subgroup_vote SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_NV_sample_mask_override_coverage SPIR-V extension= .

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_NV_geometry_shader_passthrough SPIR-V extension.<= /p>

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_NV_viewport_array2 SPIR-V extension.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_EXT_shader_viewport_index_layer SPIR-V extension.=

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_NVX_multiview_per_view_attributes SPIR-V extensio= n.

The application can pass a SPIR-V modu= le to vkCreateShaderModule that uses the SPV_EXT_descriptor_indexing SPIR-V extension.

The application must not pass a SPIR-V= module containing any of the following to vkCreateShaderModule:

  • any OpCapability not listed above,

  • an unsupported capability, or

  • a capability which corresponds to a Vulkan feature or extension which has not been enabled.

Validation Rules within a Module

A SPIR-V module passed to vkCreateShaderModule= must conform to the following rules:

  • Every entry point must have no return = value and accept no arguments.

  • Recursion: The static function-call graph for an entry point must not contain cycles.

  • The Logical addressing model m= ust be selected.

  • Scope for execution must be limited to:

    • Workgroup

    • Subgroup

  • Scope for memory must= be limited to:

    • Device

    • Workgroup

    • Subgroup

    • Invocation

  • Scope for Non Uniform Group Operations= must be limited to:

    • Subgroup

  • Storage Class must be= limited to:

    • UniformConstant

    • Input

    • Uniform

    • Output

    • Workgroup

    • Private

    • Function

    • PushConstant

    • Image

    • StorageBuffer

  • Memory semantics must obey the followi= ng rules:

    • Acquire must not be u= sed with OpAtomicStore.

    • Release must not be u= sed with OpAtomicLoad.

    • AcquireRelease must n= ot be used with OpAtomicStore or OpAtomicLoad.

    • Sequentially consistent atomics and barriers are not supported and SequentiallyConsistent is treated as AcquireReleas= e. SequentiallyConsistent should not be used.

    • OpMemoryBarrier must use = one of Acquire, Release, AcquireRelease, or SequentiallyConsistent= and must include at least one storage class.

    • If the semantics for OpControlBarrier includes one of Acquire, Release, AcquireRelease, or Seque= ntiallyConsistent, then it must include at least one storage class.

    • SubgroupMemory, CrossWorkgroupMemory, = and AtomicCounterMemory are ignored.

  • Any OpVariable with an Initializer operand must have one of the following as its Storage Class operand:

    • Output

    • Private

    • Function

  • The OriginLowerLeft execution mode must not be used; fragment entry points must declare OriginUpp= erLeft.

  • The PixelCenterInteger execution mode must not be used. Pixels are always centered at half-integer coordinates.

  • Images and Samplers

    • OpTypeImage must declare = a scalar 32-bit float or 32-bit integer type for the =E2=80=9CSampled Type=E2=80=9D. (RelaxedPrecision can be app= lied to a sampling instruction and to the variable holding the result of a sampling instruction.)

    • OpTypeImage must have a = =E2=80=9CSampled=E2=80=9D operand of 1 (sampled image) or 2 (storage image).

    • If shaderStorageImageRe= adWithoutFormat is not enabled and an OpTypeImage has =E2=80=9CImage Format=E2= =80=9D operand of Unknown, any variables created with the given type must be decorated with NonReadable.

    • If shaderStorageImageW= riteWithoutFormat is not enabled and an OpTypeImage has =E2=80=9CImage Format=E2= =80=9D operand of Unknown, any variables created with the given type must be decorated with NonWritable.

    • OpImageQuerySizeLod, and OpImageQueryLevels must only consume an =E2=80=9CImage=E2=80=9D operand whose type has its =E2=80=9CSamp= led=E2=80=9D operand set to 1.

    • The (u,v) coordinates used for a Subpass= Data must be the <id> of a constant vector (0,0), or if a la= yer coordinate is used, must be a vector that was formed wi= th constant 0 for the u and v components.

    • The =E2=80=9CDepth=E2=80=9D operand of OpTypeImage is ignor= ed.

    • Objects of types OpTypeImage, OpTypeSampler, OpTypeSampledImage, and arrays of these types must not be stored to or modified.

  • Decorations

    • The GLSLShared and GLSLPacked decorations must not be used.

    • The Flat, NoPerspective, Sample, = and Centroid decorations must not be used on variables= with storage class other than Input or on variables used in the interface of non-fragme= nt shader entry points.

    • The Patch decoration must= not be used on variables in the interface of a vertex, geometry, or fragment shader stage=E2=80=99s entry point.

    • The ViewportRelativeNV decoration = must only be used on a variable decorated with Layer in the vertex, tessellation evaluation, o= r geometry shader stages.

    • The ViewportRelativeNV decoration = must not be used unless a variable decorated with one of ViewportIndex or ViewportMaskNV is also statically used by the same OpEntryPoint.

    • The ViewportMaskNV and ViewportIndex decoratio= ns must not both be statically used by one or more OpEntryPoint=E2=80=99s = that form the vertex processing stages of a graphics pipeline.

    • Only the round-to-nearest-even and the round-to-zero rounding modes can be used for the FPRoundingMode<= /code> decoration.

    • The FPRoundingMode decoration can<= /strong> only be used for the floating-point conversion instructions as described in the SPV_KHR_16bit_storage SPIR-V extension.

    • DescriptorSet and Binding decorations must obey the constraints on storage class, type, and descriptor type described in DescriptorSet and Binding Assignment

  • OpTypeRuntimeArray must o= nly be used for:

    • the last member of an OpTypeStruct that is in the StorageBuffer storage class decorated as Block, or that is in the Uniform storage class decorated as BufferBlock.

    • If the RuntimeDescriptorArrayEXT capability is supported, a= n array of variables with storage class Uniform, StorageBuffer, or UniformConstant, or for the outermost dimension of an array= of arrays of such variables.

  • Linkage: See Shader Interfaces for additional linking an= d validation rules.

  • If OpControlBarrier is used in fragment, vertex, tessellati= on evaluation, or geometry stages, the execution Scope must be Subgroup.

  • Compute Shaders

    • For each compute shader entry point, either a LocalSize exe= cution mode or an object decorated with the WorkgroupSize decoration must be specified.

  • =E2=80=9CResult Type=E2=80=9D for Non Uniform Group Operations must be limited to 32-bit float, 32-bit integer, boolean, or vectors of these types. If the Float64 capability is enabled, double and vector of dou= ble types are also permitted.

  • =E2=80=9CMask=E2=80=9D for OpGroupNonUniformShuffleXor must be a specialization constant or a constant, or if the dynamic instance is called within a loop construct it must be one of:

    1. A specialization constant.

    2. A constant.

    3. An arthimetic operation whose operands are 1., 2., or 4.

    4. A phi node whose operands are 1., 2., or 3.

  • If OpGroupNonUniformBallotBitCount is used, the group opera= tion must be one of:

    • Reduce

    • InclusiveScan

    • ExclusiveScan

  • Atomic instructions must declare a sca= lar 32-bit integer type for the Result Type and the type of the value pointed to by Pointer.

  • If an instruction loads from or stores to a resource (including atomics and image instructions) and the resource descriptor being accessed is not dynamically uniform, then the operand corresponding to that resource (e.g. the pointer or sampled image operand) must be decorated with NonUniformEXT.

Precision and Operation of SPIR-V I= nstructions

The following rules apply to both single and double-precision floating p= oint instructions:

  • Positive and negative infinities and positive and negative zeros are generated as dictated by IEEE 754, but subject to the precisions allowed in the following table.

  • Dividing a non-zero by a zero results in the appropriately signed IEEE 754 infinity.

  • Any denormalized value input into a shader or potentially generated by any instruction in a shader may be flushe= d to 0.

  • The rounding mode cannot be set and is= undefined.

  • NaNs may not= be generated. Instructions that operate on a NaN may not result in a NaN.

  • Support for signaling NaNs is optional and exceptions are never raised.

The precision of double-precision instructions is at least that of singl= e precision.

The precision of operations is defined either in terms of rounding or as= an error bound in ULP, as follows.

Correctly Rounded

Operations described as "correctly rounded" will return the infinitely precise result, x, rounded so as to be representa= ble in floating-point. The rounding mode used is not defined but if x is= exactly representable then x will be returned. Otherwise, either the floating-point value closest to and no less than x or the value closest to and no greater than x will be returned.

ULP

Where an error bound of n ULP (units in the la= st place) is given, for an operation with infinitely precise result x the value return= ed must be in the range [x - n * ulp(x), x + n * ulp(x)]. The function ulp(x) is defined as follows:

If there exist non-equal floating-point numbers a and b such that a =E2=89=A4 x =E2=89=A4 b then ulp(x) is the minimum possible distance between such numbers, \(ulp(x) =3D \mathrm{min}_{a,b} | b - a |\). If such numbers do not exist then ulp(x) is defined to be the = difference between the two finite floating-point numbers nearest to x.

Where the range of allowed return values includes any value of magnitude larger than that of the largest representable finite floating-point number, operations may return an infinity of the appropriate sign. If the infinitely precise result of the operation is not mathematically defined then the value returned is undefined.

For single precision (32 bit) instructions, precisions are required to be at least as follows, unless decorated with RelaxedPrecision:

Table 76. Precision of core SPIR-V Instructions
Instruction Precision

OpFAdd

Cor= rectly rounded.

OpFSub

Cor= rectly rounded.

OpFMul

Cor= rectly rounded.

OpFOrdEqual, OpFUnordEqual

Cor= rect result.

OpFOrdLessThan, OpFUnordLessThan

Cor= rect result.

OpFOrdGreaterThan, OpFUnordGreaterThan

Cor= rect result.

OpFOrdLessThanEqual, OpFUnordLessThanEqual

Cor= rect result.

OpFOrdGreaterThanEqual, OpFUnordGreaterThanEqual

=

Cor= rect result.

OpFDiv

2.5= ULP for b in the range [2-126, 2126].

con= versions between types

Cor= rectly rounded.

Table 77. Precision of GLSL.std.450 Instructions
Instruction Precision

fma()

Inh= erited from OpFMul followed by OpFAdd.

exp(x), exp2(x)

3 + 2 =C3=97 |x| ULP.

log(), log2()

3 U= LP outside the range [0.5, 2.0]. Absolute error &= lt; 2-21 inside the range [0.5, 2.0].

pow(x, y)

Inh= erited from exp2(y =C3=97 log2(x)).

sqrt()

Inh= erited from 1.0 / inversesqrt().

inversesqrt()

2 U= LP.

GLSL.std.450 extended instructions specifically defined in terms of the above instructions inherit the above errors. GLSL.std.450 extended instructions not listed above and not defined in term= s of the above have undefined precision. These include, for example, the trigonometric functions and determinant.

For the OpSRem and OpSMod instructions, if eit= her operand is negative the result is undefined.

Note

While the OpSRem and OpSMod instructions are s= upported by the Vulkan environment, they require non-negative values and thus do not enable additional functionality beyond what OpUMod provides.

Compatibility Between SPIR-V Image Format= s And Vulkan Formats

Images which are read from or written to by shaders must have SPIR-V image formats compatible with the Vulkan image formats backing the image under th= e circumstances described for texture image validation. The compatibile formats are:

Table 78. SPIR-V and Vulkan Image Format Compatibi= lity
SPIR-V Image Format Compatible Vulkan Format

Rgba32f

VK_FORMAT_R32G32B32A32_SFLOAT

Rgba16f

VK_FORMAT_R16G16B16A16_SFLOAT

R32f

VK_FORMAT_R32_SFLOAT

Rgba8

VK_FORMAT_R8G8B8A8_UNORM

Rgba8Snorm

VK_FORMAT_R8G8B8A8_SNORM

Rg32f

VK_FORMAT_R32G32_SFLOAT

Rg16f

VK_FORMAT_R16G16_SFLOAT

R11fG11fB10f

VK_FORMAT_B10G11R11_UFLOAT_PACK32

R16f

VK_FORMAT_R16_SFLOAT

Rgba16

VK_FORMAT_R16G16B16A16_UNORM

Rgb10A2

VK_FORMAT_A2B10G10R10_UNORM_PACK32

Rg16

VK_FORMAT_R16G16_UNORM

Rg8

VK_FORMAT_R8G8_UNORM

R16

VK_FORMAT_R16_UNORM

R8

VK_FORMAT_R8_UNORM

Rgba16Snorm

VK_FORMAT_R16G16B16A16_SNORM

Rg16Snorm

VK_FORMAT_R16G16_SNORM

Rg8Snorm

VK_FORMAT_R8G8_SNORM

R16Snorm

VK_FORMAT_R16_SNORM

R8Snorm

VK_FORMAT_R8_SNORM

Rgba32i

VK_FORMAT_R32G32B32A32_SINT

Rgba16i

VK_FORMAT_R16G16B16A16_SINT

Rgba8i

VK_FORMAT_R8G8B8A8_SINT

R32i

VK_FORMAT_R32_SINT

Rg32i

VK_FORMAT_R32G32_SINT

Rg16i

VK_FORMAT_R16G16_SINT

Rg8i

VK_FORMAT_R8G8_SINT

R16i

VK_FORMAT_R16_SINT

R8i

VK_FORMAT_R8_SINT

Rgba32ui

VK_FORMAT_R32G32B32A32_UINT

Rgba16ui

VK_FORMAT_R16G16B16A16_UINT

Rgba8ui

VK_FORMAT_R8G8B8A8_UINT

R32ui

VK_FORMAT_R32_UINT

Rgb10a2ui

VK_FORMAT_A2B10G10R10_UINT_PACK32

Rg32ui

VK_FORMAT_R32G32_UINT

Rg16ui

VK_FORMAT_R16G16_UINT

Rg8ui

VK_FORMAT_R8G8_UINT

R16ui

VK_FORMAT_R16_UINT

R8ui

VK_FORMAT_R8_UINT

Appendix B: Compressed Image Formats

The compressed texture formats used by Vulkan are described in the specifically identified sections of the Khronos Data Format Specification, version 1.1.

Unless otherwise described, the quantities encoded in these compressed formats are treated as normalized, unsigned values.

Those formats listed as sRGB-encoded have in-memory representations of R, G and B components which are nonlinearly-encoded as R', G', and B'; any alpha component is unchanged. As part of filtering, the nonlinear R', G', and B' values are converted to linear R, G, and B components; any alpha component is unchanged. The conversion between linear and nonlinear encoding is performed as described in the =E2=80=9CKHR_DF_TRANSFER_SRGB=E2=80=9D section of the Khro= nos Data Format Specification.

Block-Compressed Image Formats

Table 79. Mapping of Vulkan BC formats to descript= ions
VkFormat Khronos Data F= ormat Specification description

Formats described in the =E2=80=9CS3TC Compressed Texture Imag= e Formats=E2=80=9D chapter

VK_FORMAT_BC1_RGB_UNORM_BLOCK

BC1= with no alpha

VK_FORMAT_BC1_RGB_SRGB_BLOCK

BC1= with no alpha, sRGB-encoded

VK_FORMAT_BC1_RGBA_UNORM_BLOCK

BC1= with alpha

VK_FORMAT_BC1_RGBA_SRGB_BLOCK

BC1= with alpha, sRGB-encoded

VK_FORMAT_BC2_UNORM_BLOCK

BC2=

VK_FORMAT_BC2_SRGB_BLOCK

BC2= , sRGB-encoded

VK_FORMAT_BC3_UNORM_BLOCK

BC3=

VK_FORMAT_BC3_SRGB_BLOCK

BC3= , sRGB-encoded

Formats described in the =E2=80=9CRGTC Compressed Texture Imag= e Formats=E2=80=9D chapter

VK_FORMAT_BC4_UNORM_BLOCK

BC4= unsigned

VK_FORMAT_BC4_SNORM_BLOCK

BC4= signed

VK_FORMAT_BC5_UNORM_BLOCK

BC5= unsigned

VK_FORMAT_BC5_SNORM_BLOCK

BC5= signed

Formats described in the =E2=80=9CBPTC Compressed Texture Imag= e Formats=E2=80=9D chapter

VK_FORMAT_BC6H_UFLOAT_BLOCK

BC6= H (unsigned version)

VK_FORMAT_BC6H_SFLOAT_BLOCK

BC6= H (signed version)

VK_FORMAT_BC7_UNORM_BLOCK

BC7=

VK_FORMAT_BC7_SRGB_BLOCK

BC7= , sRGB-encoded

ETC Compressed Image Formats

The following formats are described in the =E2=80=9CETC2 Compressed Text= ure Image Formats=E2=80=9D chapter of the Khronos Data Format Specificat= ion.

Table 80. Mapping of Vulkan ETC formats to descrip= tions
VkFormat Khronos Data F= ormat Specification description

VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK

RGB= ETC2

VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK

RGB= ETC2 with sRGB encoding

VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK

RGB= ETC2 with punch-through alpha

VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK

RGB= ETC2 with punch-through alpha and sRGB

VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK

RGB= A ETC2

VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK

RGB= A ETC2 with sRGB encoding

VK_FORMAT_EAC_R11_UNORM_BLOCK

Uns= igned R11 EAC

VK_FORMAT_EAC_R11_SNORM_BLOCK

Sig= ned R11 EAC

VK_FORMAT_EAC_R11G11_UNORM_BLOCK

Uns= igned RG11 EAC

VK_FORMAT_EAC_R11G11_SNORM_BLOCK

Sig= ned RG11 EAC

ASTC Compressed Image Formats

ASTC formats are described in the =E2=80=9CASTC Compressed Texture Image= Formats=E2=80=9D chapter of the Khronos Data Format Specification.

Table 81. Mapping of Vulkan ASTC formats to descri= ptions
VkFormat Compressed texel block di= mensions sRGB-encoded

VK_FORMAT_ASTC_4x4_UNORM_BLOCK

<= span class=3D"eq">4 =C3=97 4

N= o

VK_FORMAT_ASTC_4x4_SRGB_BLOCK

<= span class=3D"eq">4 =C3=97 4

Y= es

VK_FORMAT_ASTC_5x4_UNORM_BLOCK

<= span class=3D"eq">5 =C3=97 4

N= o

VK_FORMAT_ASTC_5x4_SRGB_BLOCK

<= span class=3D"eq">5 =C3=97 4

Y= es

VK_FORMAT_ASTC_5x5_UNORM_BLOCK

<= span class=3D"eq">5 =C3=97 5

N= o

VK_FORMAT_ASTC_5x5_SRGB_BLOCK

<= span class=3D"eq">5 =C3=97 5

Y= es

VK_FORMAT_ASTC_6x5_UNORM_BLOCK

<= span class=3D"eq">6 =C3=97 5

N= o

VK_FORMAT_ASTC_6x5_SRGB_BLOCK

<= span class=3D"eq">6 =C3=97 5

Y= es

VK_FORMAT_ASTC_6x6_UNORM_BLOCK

<= span class=3D"eq">6 =C3=97 6

N= o

VK_FORMAT_ASTC_6x6_SRGB_BLOCK

<= span class=3D"eq">6 =C3=97 6

Y= es

VK_FORMAT_ASTC_8x5_UNORM_BLOCK

<= span class=3D"eq">8 =C3=97 5

N= o

VK_FORMAT_ASTC_8x5_SRGB_BLOCK

<= span class=3D"eq">8 =C3=97 5

Y= es

VK_FORMAT_ASTC_8x6_UNORM_BLOCK

<= span class=3D"eq">8 =C3=97 6

N= o

VK_FORMAT_ASTC_8x6_SRGB_BLOCK

<= span class=3D"eq">8 =C3=97 6

Y= es

VK_FORMAT_ASTC_8x8_UNORM_BLOCK

<= span class=3D"eq">8 =C3=97 8

N= o

VK_FORMAT_ASTC_8x8_SRGB_BLOCK

<= span class=3D"eq">8 =C3=97 8

Y= es

VK_FORMAT_ASTC_10x5_UNORM_BLOCK

<= span class=3D"eq">10 =C3=97 5

N= o

VK_FORMAT_ASTC_10x5_SRGB_BLOCK

<= span class=3D"eq">10 =C3=97 5

Y= es

VK_FORMAT_ASTC_10x6_UNORM_BLOCK

<= span class=3D"eq">10 =C3=97 6

N= o

VK_FORMAT_ASTC_10x6_SRGB_BLOCK

<= span class=3D"eq">10 =C3=97 6

Y= es

VK_FORMAT_ASTC_10x8_UNORM_BLOCK

<= span class=3D"eq">10 =C3=97 8

N= o

VK_FORMAT_ASTC_10x8_SRGB_BLOCK

<= span class=3D"eq">10 =C3=97 8

Y= es

VK_FORMAT_ASTC_10x10_UNORM_BLOCK

<= span class=3D"eq">10 =C3=97 10

N= o

VK_FORMAT_ASTC_10x10_SRGB_BLOCK

<= span class=3D"eq">10 =C3=97 10

Y= es

VK_FORMAT_ASTC_12x10_UNORM_BLOCK

<= span class=3D"eq">12 =C3=97 10

N= o

VK_FORMAT_ASTC_12x10_SRGB_BLOCK

<= span class=3D"eq">12 =C3=97 10

Y= es

VK_FORMAT_ASTC_12x12_UNORM_BLOCK

<= span class=3D"eq">12 =C3=97 12

N= o

VK_FORMAT_ASTC_12x12_SRGB_BLOCK

<= span class=3D"eq">12 =C3=97 12

Y= es

Appendix C: Core Revisions (Informative)

New minor versions of the Vulkan API are defined periodically by the Khr= onos Vulkan Working Group. These consist of some amount of additional functionality added to the core API, some of which may be promoted from e= xtensions, other parts of which may be new. Extensions that are promoted in this way typically have their functionality replicated directly in the core, but with extension suffixes dropped. The existing values with suffixes are still present in the API itself as aliases of the original extension functionality. Any differences between the core and extension version of the functionality will be documented in the extension appendix, and mentioned briefly in the version description in this appendix.

It=E2=80=99s possible to build the specification for earlier versions, b= ut to aid readability of the latest versions, this appendix gives an overview of the changes as compared to earlier versions.

Version 1.1

Vulkan Version 1.1 promoted a number of key extensions into the= core API:

The only changes to the functionality added by these extensions were to VK_KHR_shader_draw_parameters, which had a feature bit added to determine support in the core API, and variablePointersStor= ageBuffer from VK_KHR_variable_pointers was made optional.

Additionally, Vulkan 1.1 added support for subgroup operations, protected memory, and a new command to enumerate the instance version.<= /p>

New Defines

New Enum Constants

  • Extending VkBufferCreateFlagBits:

    • VK_BUFFER_CREATE_PROTECTED_BIT

  • Extending VkCommandPoolCreateFlagBits:<= /p>

    • VK_COMMAND_POOL_CREATE_PROTECTED_BIT

  • Extending VkDependencyFlagBits:

    • VK_DEPENDENCY_DEVICE_GROUP_BIT

    • VK_DEPENDENCY_VIEW_LOCAL_BIT

  • Extending VkDeviceQueueCreateFlagBits:<= /p>

    • VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT

  • Extending VkFormat:

    • VK_FORMAT_G8B8G8R8_422_UNORM

    • VK_FORMAT_B8G8R8G8_422_UNORM

    • VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM

    • VK_FORMAT_G8_B8R8_2PLANE_420_UNORM

    • VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM

    • VK_FORMAT_G8_B8R8_2PLANE_422_UNORM

    • VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM

    • VK_FORMAT_R10X6_UNORM_PACK16

    • VK_FORMAT_R10X6G10X6_UNORM_2PACK16

    • VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16

    • VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16

    • VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16

    • VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16

    • VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16

    • VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16

    • VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16

    • VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16

    • VK_FORMAT_R12X4_UNORM_PACK16

    • VK_FORMAT_R12X4G12X4_UNORM_2PACK16

    • VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16

    • VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16

    • VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16

    • VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16

    • VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16

    • VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16

    • VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16

    • VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16

    • VK_FORMAT_G16B16G16R16_422_UNORM

    • VK_FORMAT_B16G16R16G16_422_UNORM

    • VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM

    • VK_FORMAT_G16_B16R16_2PLANE_420_UNORM

    • VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM

    • VK_FORMAT_G16_B16R16_2PLANE_422_UNORM

    • VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM

  • Extending VkFormatFeatureFlagBits:

    • VK_FORMAT_FEATURE_TRANSFER_SRC_BIT

    • VK_FORMAT_FEATURE_TRANSFER_DST_BIT

    • VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT=

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTR= UCTION_FILTER_BIT

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUC= TION_EXPLICIT_BIT

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUC= TION_EXPLICIT_FORCEABLE_BIT

    • VK_FORMAT_FEATURE_DISJOINT_BIT

    • VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT

  • Extending VkImageAspectFlagBits:

    • VK_IMAGE_ASPECT_PLANE_0_BIT

    • VK_IMAGE_ASPECT_PLANE_1_BIT

    • VK_IMAGE_ASPECT_PLANE_2_BIT

  • Extending VkImageCreateFlagBits:

    • VK_IMAGE_CREATE_ALIAS_BIT

    • VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT

    • VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT

    • VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT

    • VK_IMAGE_CREATE_EXTENDED_USAGE_BIT

    • VK_IMAGE_CREATE_PROTECTED_BIT

    • VK_IMAGE_CREATE_DISJOINT_BIT

  • Extending VkImageCreateFlagBits:

    • VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL<= /p>

    • VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL<= /p>

  • Extending VkMemoryHeapFlagBits:

    • VK_MEMORY_HEAP_MULTI_INSTANCE_BIT

  • Extending VkMemoryPropertyFlagBits:

    • VK_MEMORY_PROPERTY_PROTECTED_BIT

  • Extending VkObjectType:

    • VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION

    • VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE

  • Extending VkPipelineCreateFlagBits:

    • VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT

    • VK_PIPELINE_CREATE_DISPATCH_BASE

  • Extending VkQueueFlagBits:

    • VK_QUEUE_PROTECTED_BIT

  • Extending VkResult:

    • VK_ERROR_OUT_OF_POOL_MEMORY

    • VK_ERROR_INVALID_EXTERNAL_HANDLE

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES

    • VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO

    • VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES

    • VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS

    • VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO

    • VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO

    • VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO

    • VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO

    • VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2

    • VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2

    • VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2

    • VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2

    • VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2

    • VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2

    • VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2

    • VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2

    • VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES=

    • VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO<= /code>

    • VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO

    • VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE= _INFO

    • VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES=

    • VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES=

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES

    • VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2

    • VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO

    • VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO

    • VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO

    • VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURE= S

    • VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES=

    • VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO

    • VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO

    • VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES

    • VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO

    • VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO

    • VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO

    • VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES

    • VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO

    • VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO

    • VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES<= /p>

    • VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES

New Structures

Appendix D: Layers & Extensions (Informative)

Extensions to the Vulkan API can be de= fined by authors, groups of authors, and the Khronos Vulkan Working Group. In order not to compromise the readability of the Vulkan Specification, the core Specification does not incorporate most extensions. The online Registry of extensions is available at URL

and allows generating versions of the Specification incorporating differ= ent extensions.

Most of the content previously in this appendix does not specify use of specific Vulkan extensions and layers, but rather specifies the processes b= y which extensions and layers are created. As of version 1.0.21 of the Vulkan Specification, this content has been migrated to the Vulkan Documentation and Extensions document. Authors creating extensions and layers must follow the mandatory procedures in that document.

The remainder of this appendix documents a set of extensions chosen when this document was built. Versions of the Specification published in the Registry include:

  • Core API + mandatory extensions required of all Vulkan implementations.<= /p>

  • Core API + all registered and published Khronos (KHR) exten= sions.

  • Core API + all registered and published extensions.

Extensions are grouped as Khronos KHR, multivendor EX= T, and then alphabetically by author ID. Within each group, extensions are listed in alphabetical order by their name.

Note

As of the initial Vulkan 1.1 public release, the KHX author= ID is no longer used. All KHX extensions have been promoted to KHR stat= us. Previously, this author ID was used to indicate that an extension was experimental, and is being considered for standardization in future K= HR or core Vulkan API versions. We no longer use this mechanism for exposing experimental functionality.

Some vendors may use an alternate author ID ending in X for= some of their extensions. The exact meaning of such an author ID is defined by each vendor, and may not be equivalent to KHX, but it is likely to indicate a lesse= r degree of interface stability than a non-X extension from the same vendo= r.

List of Current Extensions

VK_KHR_8bit_storage

Name String

VK_KHR_8bit_storage

Extension Type

Device extension

Registered Extension Number

178

Revision

1

Extension and Version Dependencies
Contact
  • Alexander Galazin @alegal-arm

Last Modified Date

2018-02-05

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Alexander Galazin, Arm

The VK_KHR_8bit_storage extension allows use of 8-bit types in uniform a= nd storage buffers, and push constant blocks. This extension introduces several new optional features which map to SPIR-V capabilities and allow access to 8-bit data in Block-decorated= objects in the Uniform and the StorageBuffer storage clas= ses, and objects in the PushConstant storage class.

The StorageBuffer8BitAccess capability must be supported by all implementations of this extension. The other capabilities are optional.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR=

Issues

Version History

  • Revision 1, 2018-02-05 (Alexander Galazin)

    • Initial draft

VK_KHR_android_surface

Name String

VK_KHR_android_surface

Extension Type

Instance extension

Registered Extension Number

9

Revision

6

Extension and Version Dependencies
Contact
  • Jesse Hall @critsec

Last Modified Date

2016-01-14

IP Status

No known IP claims.

Contributors
  • Patrick Doane, Blizzard

  • Jason Ekstrand, Intel

  • Ian Elliott, LunarG

  • Courtney Goeltzenleuchter, LunarG

  • Jesse Hall, Google

  • James Jones, NVIDIA

  • Antoine Labour, Google

  • Jon Leech, Khronos

  • David Mao, AMD

  • Norbert Nopper, Freescale

  • Alon Or-bach, Samsung

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Ray Smith, ARM

  • Jeff Vigil, Qualcomm

  • Chia-I Wu, LunarG

The VK_KHR_android_surface extension is an instance extensi= on. It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) that refers = to an ANativeWindow, Android=E2=80=99s native surface type. The ANativeWindow represents the producer endpoint of any buff= er queue, regardless of consumer endpoint. Common consumer endpoints for ANativeWindows are the system wi= ndow compositor, video encoders, and application-specific compositors importing the images through a SurfaceTexture.

New Object Types

None

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR

New Enums

None

Issues

1) Does Android need a way to query for compatibility between a particul= ar physical device (and queue family?) and a specific Android display?

RESOLVED: No. Currently on Android, any physical device is expected to be able to present to the system compositor, and all queue families must support the necessary image layout transitions and synchronization operations.

Version History

  • Revision 1, 2015-09-23 (Jesse Hall)

    • Initial draft.

  • Revision 2, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_android_surface to VK_KHR_android_surface.

  • Revision 3, 2015-11-03 (Daniel Rakos)

    • Added allocation callbacks to surface creation function.

  • Revision 4, 2015-11-10 (Jesse Hall)

    • Removed VK_ERROR_INVALID_ANDROID_WINDOW_KHR.

  • Revision 5, 2015-11-28 (Daniel Rakos)

    • Updated the surface create function to take a pCreateInfo structure.

  • Revision 6, 2016-01-14 (James Jones)

    • Moved VK_ERROR_NATIVE_WINDOW_IN_USE_KHR from the VK_KHR_android_surface to the VK_KHR_surface extension.

VK_KHR_create_renderpass2

Name String

VK_KHR_create_renderpass2

Extension Type

Device extension

Registered Extension Number

110

Revision

1

Extension and Version Dependencies
Contact
  • Tobias Hector @tobias

Last Modified Date

2018-02-07

Contributors
  • Tobias Hector

  • Jeff Bolz

This extension provides a new entry point to create render passes in a w= ay that can be easily extended by other extensions through the substructures o= f render pass creation. The Vulkan 1.0 render pass creation sub-structures do not include sType/pNext members. Additionally, the renderpass begin/next/end commands have been augmented with new extensible structures for passing additional subpass information.<= /p>

Parameters from the VK_KHR_multiview and VK_KHR_maintenance2 extensions which previously extended VkRenderPassCr= eateInfo are folded into the new structures in more appropriate locations.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR

    • VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR

    • VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR

    • VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR

    • VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR

    • VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR

    • VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR

Version History

  • Revision 1, 2018-02-07 (Tobias Hector)

    • Internal revisions

VK_KHR_display

Name String

VK_KHR_display

Extension Type

Instance extension

Registered Extension Number

3

Revision

21

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

  • Norbert Nopper @FslNopper

Last Modified Date

2017-03-13

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Norbert Nopper, Freescale

  • Jeff Vigil, Qualcomm

  • Daniel Rakos, AMD

This extension provides the API to enumerate displays and available mode= s on a given device.

New Object Types

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR

    • VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR

Issues

1) Which properties of a mode should be fixed in the mode info vs. settable in some other function when setting the mode? E.g., do we need to double the size of the mode pool to include both stereo and non-stereo modes? YUV and RGB scanout even if they both take RGB input images? BGR vs. RGB input? etc.

PROPOSED RESOLUTION: Many modern displays support at mo= st a handful of resolutions and timings natively. Other =E2=80=9Cmodes=E2=80=9D are expected to be supported using scaling ha= rdware on the display engine or GPU. Other properties, such as rotation and mirroring should not require duplicating hardware modes just to express all combinations. Further, these properties may be implemented on a per-display or per-overla= y granularity.

To avoid the exponential growth of modes as mutable properties are added= , as was the case with EGLConfig/WGL pixel formats/GLXFBConfi= g, this specification should separate out hardware properties and configurable stat= e into separate objects. Modes and overlay planes will express capabilities of the hardware, while a separate structure will allow applications to configure scaling, rotation, mirroring, color keys, LUT values, alpha masks, etc. for a given swapchain independent of the mode in use. Constraints on these settings will be established by properties of the immutable objects.

Note the resolution of this issue may affect issue 5 as well.

2) What properties of a display itself are useful?

PROPOSED RESOLUTION: This issue is too broad. It was meant to prompt general discussion, but resolving this issue amounts to completing this specification. All interesting properties should be included. The issue will remain as a placeholder since removing it would make it hard to parse existing discussion notes that refer to issues by number.

3) How are multiple overlay planes within a display or mode enumerated?<= /p>

PROPOSED RESOLUTION: They are referred to by an index. Each display will report the number of overlay planes it contains.

4) Should swapchains be created relative to a mode or a display?

PROPOSED RESOLUTION: When using this extension, swapcha= ins are created relative to a mode and a plane. The mode implies the display object the swapchain will present to. If the specified mode is not the display=E2=80=99s current mode, the new mo= de will be applied when the first image is presented to the swapchain, and the default operating system mode, if any, will be restored when the swapchain is destroyed.

5) Should users query generic ranges from displays and construct their o= wn modes explicitly using those constraints rather than querying a fixed set o= f modes (Most monitors only have one real =E2=80=9Cmode=E2=80=9D these days, = even though many support relatively arbitrary scaling, either on the monitor side or in the GPU display engine, making =E2=80=9Cmodes=E2=80=9D something of a relic= /compatibility construct).

PROPOSED RESOLUTION: Expose both. Display info structures will expose a set of predefined modes, as well as any attributes necessary to construct a customized mode.

6) Is it fine if we return the display and display mode handles in the structure used to query their properties?

PROPOSED RESOLUTION: Yes.

7) Is there a possibility that not all displays of a device work with al= l of the present queues of a device? If yes, how do we determine which displays work with which present queues?

PROPOSED RESOLUTION: No known hardware has such limitat= ions, but determining such limitations is supported automatically using the existing VK_KHR_surface and VK_KHR_swapchain query mechanisms.

8) Should all presentation need to be done relative to an overlay plane,= or can a display mode + display be used alone to target an output?

PROPOSED RESOLUTION: Require specifying a plane explici= tly.

9) Should displays have an associated window system display, such as an HDC or Display*?

PROPOSED RESOLUTION: No. Displays are independent of any windowing system in use on the system. Further, neither HDC nor Display* refer to a phys= ical display object.

10) Are displays queried from a physical GPU or from a device instance?<= /p>

PROPOSED RESOLUTION: Developers prefer to query modes d= irectly from the physical GPU so they can use display information as an input to their devic= e selection algorithms prior to device creation. This avoids the need to create dummy device instances to enumerate displays= .

This preference must be weighed against the extra initialization that mu= st be done by driver vendors prior to device instance creation to support this usage.

11) Should displays and/or modes be dispatchable objects? If functions a= re to take displays, overlays, or modes as their first parameter, they must be dispatchable objects as defined in Khronos bug 13529. If they are not added to the list of dispatchable objects, functions operating on them must take some higher-level object as their first parameter. There is no performance case against making them dispatchable objects, but they would be the first extension objects to be dispatchable.

PROPOSED RESOLUTION: Do not make displays or modes disp= atchable. They will dispatch based on their associated physical device.

12) Should hardware cursor capabilities be exposed?

PROPOSED RESOLUTION: Defer. This could be a separate extension on top of the base WSI specs.

editing-note

There appears to be a missing sentence for the first part of issue 13 he= re.

if they are one physical display device to an end user, but may internal= ly be implemented as two side-by-side displays using the same display engine (and sometimes cabling) resources as two physically separate display devices.

RESOLVED: Tiled displays will appear as a single displa= y object in this API.

14) Should the raw EDID data be included in the display information?

RESOLVED: No. A future extension could be added which reports the EDID if necessary. This may be complicated by the outcome of issue 13.

15) Should min and max scaling factor capabilities of overlays be expose= d?

RESOLVED: Yes. This is exposed indirectly by allowing applications to query the min/max position and extent of the source and destination regions from which image contents are fetched by the display engine when using a particular mode and overlay pair.

16) Should devices be able to expose planes that can be moved between displays? If so, how?

RESOLVED: Yes. Applications can determine which displays a given plane supports using vkGetDisplayPlaneSupportedDisplaysKH= R.

17) Should there be a way to destroy display modes? If so, does it suppo= rt destroying =E2=80=9Cbuilt in=E2=80=9D modes?

RESOLVED: Not in this extension. A future extension could add this functionality.

18) What should the lifetime of display and built-in display mode object= s be?

RESOLVED: The lifetime of the instance. These objects cannot be destroyed. A future extension may be added to expose a way to destroy these objects and/or support display hotplug.

19) Should persistent mode for smart panels be enabled/disabled at swapc= hain creation time, or on a per-present basis.

RESOLVED: On a per-present basis.

Examples

Note

The example code for the VK_KHR_display and VK_KHR_display_swapchain extensions was removed from the appendix after revision 1.0.43. The display enumeration example code was ported to the cube demo that is shipped with the official Khronos SDK, and is being kept up-to-date in that location (see: https://github.com/KhronosGroup/Vulkan-Tools/blob/mast= er/cube/cube.c).

Version History

  • Revision 1, 2015-02-24 (James Jones)

    • Initial draft

  • Revision 2, 2015-03-12 (Norbert Nopper)

    • Added overlay enumeration for a display.

  • Revision 3, 2015-03-17 (Norbert Nopper)

    • Fixed typos and namings as discussed in Bugzilla.

    • Reordered and grouped functions.

    • Added functions to query count of display, mode and overlay.

    • Added native display handle, which is maybe needed on some platforms to create a native Window.

  • Revision 4, 2015-03-18 (Norbert Nopper)

    • Removed primary and virtualPostion members (see comment of James Jones in Bugzilla).

    • Added native overlay handle to info structure.

    • Replaced , with ; in struct.

  • Revision 6, 2015-03-18 (Daniel Rakos)

    • Added WSI extension suffix to all items.

    • Made the whole API more "Vulkanish".

    • Replaced all functions with a single vkGetDisplayInfoKHR function to better match the rest of the API.

    • Made the display, display mode, and overlay objects be first class objects, not subclasses of VkBaseObject as they do not support the common functions anyways.

    • Renamed *Info structures to *Properties.

    • Removed overlayIndex field from VkOverlayProperties as there is an implicit index already as a result of moving to a "Vulkanish" API.

    • Displays are not get through device, but through physical GPU to match the rest of the Vulkan API. Also this is something ISVs explicitly requested.

    • Added issue (6) and (7).

  • Revision 7, 2015-03-25 (James Jones)

    • Added an issues section

    • Added rotation and mirroring flags

  • Revision 8, 2015-03-25 (James Jones)

    • Combined the duplicate issues sections introduced in last change.

    • Added proposed resolutions to several issues.

  • Revision 9, 2015-04-01 (Daniel Rakos)

    • Rebased extension against Vulkan 0.82.0

  • Revision 10, 2015-04-01 (James Jones)

    • Added issues (10) and (11).

    • Added more straw-man issue resolutions, and cleaned up the proposed resolution for issue (4).

    • Updated the rotation and mirroring enums to have proper bitmask semantics.

  • Revision 11, 2015-04-15 (James Jones)

    • Added proposed resolution for issues (1) and (2).

    • Added issues (12), (13), (14), and (15)

    • Removed pNativeHandle field from overlay structure.

    • Fixed small compilation errors in example code.

  • Revision 12, 2015-07-29 (James Jones)

    • Rewrote the guts of the extension against the latest WSI swapchain specifications and the latest Vulkan API.

    • Address overlay planes by their index rather than an object handle and refer to them as "planes" rather than "overlays" to make it slightly clearer that even a display with no "overlays" still has at least one base "plane" that images can be displayed on.

    • Updated most of the issues.

    • Added an "extension type" section to the specification header.

    • Re-used the VK_EXT_KHR_surface surface transform enumerations rather than redefining them here.

    • Updated the example code to use the new semantics.

  • Revision 13, 2015-08-21 (Ian Elliott)

    • Renamed this extension and all of its enumerations, types, functions, etc. This makes it compliant with the proposed standard for Vulkan extensions.

    • Switched from "revision" to "version", including use of the VK_MAKE_VERSION macro in the header file.

  • Revision 14, 2015-09-01 (James Jones)

    • Restore single-field revision number.

  • Revision 15, 2015-09-08 (James Jones)

    • Added alpha flags enum.

    • Added premultiplied alpha support.

  • Revision 16, 2015-09-08 (James Jones)

    • Added description section to the spec.

    • Added issues 16 - 18.

  • Revision 17, 2015-10-02 (James Jones)

    • Planes are now a property of the entire device rather than individual displays. This allows planes to be moved between multiple displays on devices that support it.

    • Added a function to create a VkSurfaceKHR object describing a display plane and mode to align with the new per-platform surface creation conventions.

    • Removed detailed mode timing data. It was agreed that the mode extents and refresh rate are sufficient for current use cases. Other information could be added back2 in as an extension if it is needed in the future.

    • Added support for smart/persistent/buffered display devices.

  • Revision 18, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_display to VK_KHR_display.

  • Revision 19, 2015-11-02 (James Jones)

    • Updated example code to match revision 17 changes.

  • Revision 20, 2015-11-03 (Daniel Rakos)

    • Added allocation callbacks to creation functions.

  • Revision 21, 2015-11-10 (Jesse Hall)

    • Added VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR, and use VkDisplayPlaneAlphaFlagBitsKHR for VkDisplayPlanePropertiesKHR::alphaMode instead of VkDisplayPlaneAlphaFlagsKHR, since it only represents one mode.

    • Added reserved flags bitmask to VkDisplayPlanePropertiesKHR.

    • Use VkSurfaceTransformFlagBitsKHR instead of obsolete VkSurfaceTransformKHR.

    • Renamed vkGetDisplayPlaneSupportedDisplaysKHR parameters for clarity.

  • Revision 22, 2015-12-18 (James Jones)

    • Added missing "planeIndex" parameter to vkGetDisplayPlaneSupportedDisplaysKHR()

  • Revision 23, 2017-03-13 (James Jones)

    • Closed all remaining issues. The specification and implementations have been shipping with the proposed resolutions for some time now.

    • Removed the sample code and noted it has been integrated into the official Vulkan SDK cube demo.

VK_KHR_display_swapchain

Name String

VK_KHR_display_swapchain

Extension Type

Device extension

Registered Extension Number

4

Revision

9

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2017-03-13

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Jeff Vigil, Qualcomm

  • Jesse Hall, Google

This extension provides an API to create a swapchain directly on a devic= e=E2=80=99s display without any underlying window system.

New Object Types

None

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR

  • Extending VkResult:

    • VK_ERROR_INCOMPATIBLE_DISPLAY_KHR

New Enums

None

New Structures

Issues

1) Should swapchains sharing images each hold a reference to the images,= or should it be up to the application to destroy the swapchains and images in an order that avoids the need for reference counting?

RESOLVED: Take a reference. The lifetime of presentable images is already complex enough.

2) Should the srcRect/dstRect parameters be sp= ecified as part of the present command, or at swapchain creation time?

RESOLVED: As part of the presentation command. This allows moving and scaling the image on the screen without the need to respecify the mode or create a new swapchain and presentable images.

3) Should srcRect/dstRect be specified as rect= s, or separate offset/extent values?

RESOLVED: As rects. Specifying them separately might make it easier for hardware to expose support for one but not the other, but in such cases applications must just take care to obey the reported capabilities and not use non-zero offsets or extents that require scaling, as appropriate.

4) How can applications create multiple swapchains that use the same ima= ges?

RESOLVED: By calling vkCre= ateSharedSwapchainsKHR.

An earlier resolution used vkCreateSwapchainKHR, chaining multiple VkSwapchainCreateInfoKHR structures through <= code>pNext. In order to allow each swapchain to also allow other extension structs, a level of indirection was used: VkSwapchainCreateI= nfoKHR::pNext pointed to a different structure, which had both an sType/pNext for additional extensions, and also had a pointer to the next VkSwapchainCreateInfoKHR structure. The number of swapchains to be created could only be found by walking this linked list of alternating structures, and the pSwapchains out parameter was reinterpreted to be an array of VkSwapchainKH= R handles.

Another option considered was a method to specify a =E2=80=9Cshared=E2= =80=9D swapchain when creating a new swapchain, such that groups of swapchains using the sam= e images could be built up one at a time. This was deemed unusable because drivers need to know all of the displays a= n image will be used on when determining which internal formats and layouts t= o use for that image.

Examples

Note

The example code for the VK_KHR_display= and VK_KHR_display_swapchain extensions was removed from the appendix after revision 1.0.43. The display swapchain creation example code was ported to the cube demo tha= t is shipped with the official Khronos SDK, and is being kept up-to-date in that location (see: https://github.com/KhronosGroup/Vulkan-Tools/blob/mast= er/cube/cube.c).

Version History

  • Revision 1, 2015-07-29 (James Jones)

    • Initial draft

  • Revision 2, 2015-08-21 (Ian Elliott)

    • Renamed this extension and all of its enumerations, types, functions, etc. This makes it compliant with the proposed standard for Vulkan extensions.

    • Switched from "revision" to "version", including use of the VK_MAKE_VERSION macro in the header file.

  • Revision 3, 2015-09-01 (James Jones)

    • Restore single-field revision number.

  • Revision 4, 2015-09-08 (James Jones)

    • Allow creating multiple swap chains that share the same images using a single call to vkCreateSwapChainKHR().

  • Revision 5, 2015-09-10 (Alon Or-bach)

    • Removed underscores from SWAP_CHAIN in two enums.

  • Revision 6, 2015-10-02 (James Jones)

    • Added support for smart panels/buffered displays.

  • Revision 7, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_display_swapchain to VK_KHR_display_swapchain.

  • Revision 8, 2015-11-03 (Daniel Rakos)

    • Updated sample code based on the changes to VK_KHR_swapchain.

  • Revision 9, 2015-11-10 (Jesse Hall)

    • Replaced VkDisplaySwapchainCreateInfoKHR with vkCreateSharedSwapchainsKHR, changing resolution of issue #4.

  • Revision 10, 2017-03-13 (James Jones)

    • Closed all remaining issues. The specification and implementations have been shipping with the proposed resolutions for some time now.

    • Removed the sample code and noted it has been integrated into the official Vulkan SDK cube demo.

VK_KHR_draw_indirect_count

Name String

VK_KHR_draw_indirect_count

Extension Type

Device extension

Registered Extension Number

170

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Piers Daniell @pdaniell-nv

Status

Draft

Last Modified Date

2017-08-25

IP Status

No known IP claims.

Contributors
  • Matthaeus G. Chajdas, AMD

  • Derrick Owens, AMD

  • Graham Sellers, AMD

  • Daniel Rakos, AMD

  • Dominik Witczak, AMD

  • Piers Daniell, NVIDIA

This extension is based off the VK_AMD_draw_indirect_count extension. This extension allows an application to source the number of draw calls for indirect draw calls from a buffer. This enables applications to generate arbitrary amounts of draw commands an= d execute them without host intervention.

Version History

  • Revision 1, 2017-08-25 (Piers Daniell)

    • Initial draft based off VK_AMD_draw_indirect_count

VK_KHR_external_fence_fd

Name String

VK_KHR_external_fence_fd

Extension Type

Device extension

Registered Extension Number

116

Revision

1

Extension and Version Dependencies
Contact
  • Jesse Hall @critsec

Last Modified Date

2017-05-08

IP Status

No known IP claims.

Contributors

An application using external memory may wish to synchronize access to t= hat memory using fences. This extension enables an application to export fence payload to and import fence payload from POSIX file descriptors.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR

  • VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR

New Enums

None.

Issues

This extension borrows concepts, semantics, and language from VK_KHR_external_semaphore_fd= . That extension=E2=80=99s issues apply equally to this extension.

VK_KHR_external_fence_win32

Name String

VK_KHR_external_fence_win32

Extension Type

Device extension

Registered Extension Number

115

Revision

1

Extension and Version Dependencies
Contact
  • Jesse Hall @critsec

Last Modified Date

2017-05-08

IP Status

No known IP claims.

Contributors

An application using external memory may wish to synchronize access to t= hat memory using fences. This extension enables an application to export fence payload to and import fence payload from Windows handles.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR

  • VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR

  • VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR

New Enums

None.

Issues

This extension borrows concepts, semantics, and language from VK_KHR_external_semaphore_win32<= /code>. That extension=E2=80=99s issues apply equally to this extension.

1) Should D3D12 fence handle types be supported, like they are for semaphores?

RESOLVED: No. Doing so would require extending the fence signal and wait operations to provide values to signal / wait for, like VkD3D12FenceSubmitInfoKHR does. A D3D12 fence can be signaled by importing it into a VkSemapho= re instead of a VkFence, and applications can check status or wai= t on the D3D12 fence using non-Vulkan APIs. The convenience of being able to do these operations on VkFence objects doesn=E2=80=99t justify the extra API complexity.

VK_KHR_external_memory_fd

Name String

VK_KHR_external_memory_fd

Extension Type

Device extension

Registered Extension Number

75

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2016-10-21

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Jeff Juliano, NVIDIA

An application may wish to reference device memory in multiple Vulkan logical devices or instances, in multiple processes, and/or in multiple APIs. This extension enables an application to export POSIX file descriptor handles from Vulkan memory objects and to import Vulkan memory objects from POSIX file descriptor handles exported from other Vulkan memory objects or from similar resources in other APIs.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR

  • VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR

  • VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR

New Enums

None.

Issues

1) Does the application need to close the file descriptor returned by vkGetMemoryFdKHR?

RESOLVED: Yes, unless it is passed back in to a driver = instance to import the memory. A successful get call transfers ownership of the file descriptor to the application, and a successful import transfers it back to the driver. Destroying the original memory object will not close the file descriptor or remove its reference to the underlying memory resource associated with it.<= /p>

2) Do drivers ever need to expose multiple file descriptors per memory object?

RESOLVED: No. This would indicate there are actually multiple memory objects, rather than a single memory object.

3) How should the valid size and memory type for POSIX file descriptor memory handles created outside of Vulkan be specified?

RESOLVED: The valid memory types are queried directly f= rom the external handle. The size will be specified by future extensions that introduce such externa= l memory handle types.

VK_KHR_external_memory_win32

Name String

VK_KHR_external_memory_win32

Extension Type

Device extension

Registered Extension Number

74

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2016-10-21

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Jeff Juliano, NVIDIA

  • Carsten Rohde, NVIDIA

An application may wish to reference device memory in multiple Vulkan logical devices or instances, in multiple processes, and/or in multiple APIs. This extension enables an application to export Windows handles from Vulkan memory objects and to import Vulkan memory objects from Windows handles exported from other Vulkan memory objects or from similar resources in othe= r APIs.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR

  • VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR

  • VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR

  • VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR

New Enums

None.

Issues

1) Do applications need to call CloseHandle() on the values= returned from vkGetMemoryWin32HandleKHR when ha= ndleType is VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR?

editing-note

(Jon) This issue refers to a token from VK_KHR_external_semaphore_win32<= /code>, but there=E2=80=99s no dependency or interaction with that extension defined above.

RESOLVED: Yes, unless it is passed back in to another d= river instance to import the object. A successful get call transfers ownership of the handle to the application. Destroying the memory object will not destroy the handle or the handle=E2= =80=99s reference to the underlying memory resource.

2) Should the language regarding KMT/Windows 7 handles be moved to a separate extension so that it can be deprecated over time?

RESOLVED: No. Support for them can be deprecated by drivers if they choose, by no longer returning them in the supported handle types of the instance level queries.=

3) How should the valid size and memory type for windows memory handles created outside of Vulkan be specified?

RESOLVED: The valid memory types are queried directly f= rom the external handle. The size is determined by the associated image or buffer memory requirement= s for external handle types that require dedicated allocations, and by the size specified when creating the object from which the handle was exported for other external handle types.

VK_KHR_external_semaphore_fd

Name String

VK_KHR_external_semaphore_fd

Extension Type

Device extension

Registered Extension Number

80

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2016-10-21

IP Status

No known IP claims.

Contributors
  • Jesse Hall, Google

  • James Jones, NVIDIA

  • Jeff Juliano, NVIDIA

  • Carsten Rohde, NVIDIA

An application using external memory may wish to synchronize access to t= hat memory using semaphores. This extension enables an application to export semaphore payload to and import semaphore payload from POSIX file descriptors.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR

  • VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR

New Enums

None.

Issues

1) Does the application need to close the file descriptor returned by vkGetSemaphoreFdKHR?

RESOLVED: Yes, unless it is passed back in to a driver = instance to import the semaphore. A successful get call transfers ownership of the file descriptor to the application, and a successful import transfers it back to the driver. Destroying the original semaphore object will not close the file descriptor or remove its reference to the underlying semaphore resource associated wit= h it.

VK_KHR_external_semaphore_win32<= /h4>
Name String

VK_KHR_external_semaphore_win32

Extension Type

Device extension

Registered Extension Number

79

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2016-10-21

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Jeff Juliano, NVIDIA

  • Carsten Rohde, NVIDIA

An application using external memory may wish to synchronize access to t= hat memory using semaphores. This extension enables an application to export semaphore payload to and import semaphore payload from Windows handles.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR

  • VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR

  • VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR

  • VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR

New Enums

None.

Issues

1) Do applications need to call CloseHandle() on the values= returned from vkGetSemaphoreWin32HandleKHR when handleType is VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR?

RESOLVED: Yes, unless it is passed back in to another d= river instance to import the object. A successful get call transfers ownership of the handle to the application. Destroying the semaphore object will not destroy the handle or the handle= =E2=80=99s reference to the underlying semaphore resource.

2) Should the language regarding KMT/Windows 7 handles be moved to a separate extension so that it can be deprecated over time?

RESOLVED: No. Support for them can be deprecated by drivers if they choose, by no longer returning them in the supported handle types of the instance level queries.=

3) Should applications be allowed to specify additional object attribute= s for shared handles?

RESOLVED: Yes. Applications will be allowed to provide similar attributes to those they would to any other handle creation API.

4) How do applications communicate the desired fence values to use with D3D12_FENCE-based Vulkan semaphores?

RESOLVED: There are a couple of options. The values for the signaled and reset states could be communicated up front when creating the object and remain static for the life of the Vulkan semaphore, or they could be specified using auxiliary structures when submitting semaphore signal and wait operations, similar to what is done with the keyed mutex extensions. The latter is more flexible and consistent with the keyed mutex usage, but the former is a much simpler API.

Since Vulkan tends to favor flexibility and consistency over simplicity,= a new structure specifying D3D12 fence acquire and release values is added to the vkQueueSubmit function.

VK_KHR_get_display_properties2
Name String

VK_KHR_get_display_properties2

Extension Type

Instance extension

Registered Extension Number

122

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2017-02-21

IP Status

No known IP claims.

Contributors
  • Ian Elliott, Google

  • James Jones, NVIDIA

This extension provides new entry points to query device display propert= ies and capabilities in a way that can be easily extended by other extensions, without introducing any further entry points. This extension can be considered the VK_KHR_display equivalent of the VK_KHR_get_physic= al_device_properties2 extension.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR

    • VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR

New Enums

None.

Issues

1) What should this extension be named?

RESOLVED: VK_KHR_get_display_properties2. Other alternatives:

  • VK_KHR_display2

  • One extension, combined with VK_KHR_surface_capabilites2.

2) Should extensible input structs be added for these new functions:

RESOLVED:

3) Should additional display query functions be extended?

RESOLVED:

Version History

  • Revision 1, 2017-02-21 (James Jones)

    • Initial draft.

VK_KHR_get_surface_capabilities= 2

Name String

VK_KHR_get_surface_capabilities2

Extension Type

Instance extension

Registered Extension Number

120

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2017-02-27

IP Status

No known IP claims.

Contributors
  • Ian Elliott, Google

  • James Jones, NVIDIA

  • Alon Or-bach, Samsung

This extension provides new entry points to query device surface capabilities in a way that can be easily extended by other extensions, without introducing any further entry points. This extension can be considered the VK_KHR_surface equivalent of the VK_KHR_get_physical_device_pr= operties2 extension.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR

    • VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR

    • VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR

New Enums

None.

Issues

1) What should this extension be named?

RESOLVED: VK_KHR_get_surface_capabilities2= . Other alternatives:

  • VK_KHR_surface2

  • One extension, combining a separate display-specific query extension.

2) Should additional WSI query functions be extended?

RESOLVED:

Version History

  • Revision 1, 2017-02-27 (James Jones)

    • Initial draft.

VK_KHR_image_format_list

Name String

VK_KHR_image_format_list

Extension Type

Device extension

Registered Extension Number

148

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Jason Ekstrand @jekstrand

Last Modified Date

2017-03-20

IP Status

No known IP claims.

Contributors
  • Jason Ekstrand, Intel

  • Jan-Harald Fredriksen, ARM

  • Jeff Bolz, NVIDIA

  • Jeff Leger, Qualcomm

  • Neil Henning, Codeplay

On some implementations, setting the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT on image creation can cause= access to that image to perform worse than an equivalent image created without VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT because the implementation = does not know what view formats will be paired with the image.

This extension allows an application to provide the list of all formats = that can be used with an image when it is crea= ted. The implementation may then be able to create a more efficient image that supports the subset of formats required by the application without having t= o support all formats in the format compatibility class of the image format.<= /p>

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR

New Enums

None.

New Functions

None.

Issues

VK_KHR_incremental_present

Name String

VK_KHR_incremental_present

Extension Type

Device extension

Registered Extension Number

85

Revision

1

Extension and Version Dependencies
Contact
  • Ian Elliott @ianelliottus

Last Modified Date

2016-11-02

IP Status

No known IP claims.

Contributors
  • Ian Elliott, Google

  • Jesse Hall, Google

  • Alon Or-bach, Samsung

  • James Jones, NVIDIA

  • Daniel Rakos, AMD

  • Ray Smith, ARM

  • Mika Isojarvi, Google

  • Jeff Juliano, NVIDIA

  • Jeff Bolz, NVIDIA

This device extension extends vkQueuePresentKHR, = from the VK_KHR_swapchain extension, allowing an = application to specify a list of rectangular, modified regions of each image to present. This should be used in situations where an application is only changing a small portion of the presentable images within a swapchain, since it enable= s the presentation engine to avoid wasting time presenting parts of the surface that haven=E2=80=99t changed.

This extension is leveraged from the EGL_KHR_swap_buffers_with_damage extension.

New Object Types

None.

New Enum Constants

New Enums

None.

New Functions

None.

Examples

None.

Issues

1) How should we handle steroescopic-3D swapchains? We need to add a lay= er for each rectangle. One approach is to create another struct that contains the VkRect= 2D plus layer, and have VkPresentRegionsKHR point to = an array of that struct. Another approach is to have two parallel arrays, pRectangles a= nd pLayers, where pRectangles[i] and pLayers[i] must be used together. Which approach should we use, and if the array of a new structure, what should that be called?

RESOLVED: Create a new structure, which is a = VkRect2D plus a layer, and will be called VkRectLayerKHR.

2) Where is the origin of the VkRectLayerKHR?

RESOLVED: The upper left corner of the presentable imag= e(s) of the swapchain, per the definition of framebuffer coordinates.

3) Does the rectangular region, VkRectLayerKHR, spec= ify pixels of the swapchain=E2=80=99s image(s), or of the surface?

RESOLVED: Of the image(s). Some presentation engines may scale the pixels of a swapchain=E2=80=99s ima= ge(s) to the size of the surface. The size of the swapchain=E2=80=99s image(s) will be consistent, where the = size of the surface may vary over time.

4) What if all of the rectangles for a given swapchain contain a width and/or height of zero?

RESOLVED: The application is indicating that no pixels = changed since the last present. The presentation engine may use such a hint and not update any pixels for the swapchain. However, all other semantics of vkQueuePresentKHR mu= st still be honored, including waiting for semaphores to signal.

Version History

  • Revision 1, 2016-11-02 (Ian Elliott)

    • Internal revisions

VK_KHR_mir_surface

Name String

VK_KHR_mir_surface

Extension Type

Instance extension

Registered Extension Number

8

Revision

4

Extension and Version Dependencies
Contact
  • Jesse Hall @critsec

  • Ian Elliott @ianelliottus

Last Modified Date

2015-11-28

IP Status

No known IP claims.

Contributors
  • Patrick Doane, Blizzard

  • Jason Ekstrand, Intel

  • Ian Elliott, LunarG

  • Courtney Goeltzenleuchter, LunarG

  • Jesse Hall, Google

  • James Jones, NVIDIA

  • Antoine Labour, Google

  • Jon Leech, Khronos

  • David Mao, AMD

  • Norbert Nopper, Freescale

  • Alon Or-bach, Samsung

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Ray Smith, ARM

  • Jeff Vigil, Qualcomm

  • Chia-I Wu, LunarG

The VK_KHR_mir_surface extension is an instance extension. It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) that refers = to a Mir surface, as well as a query to determine support for rendering to the windows desktop.

New Object Types

None

New Enum Constants

New Enums

None

New Structures

Issues

1) Does Mir need a way to query for compatibility between a particular physical device (and queue family?) and a specific Mir connection, screen, window, etc.?

RESOLVED: Yes, vkGetPhysicalDeviceMirPresentationSupportKHR was added to address this.

Version History

  • Revision 1, 2015-09-23 (Jesse Hall)

    • Initial draft, based on the previous contents of VK_EXT_KHR_swapchain (later renamed VK_EXT_KHR_surface).

  • Revision 2, 2015-10-02 (James Jones)

    • Added vkGetPhysicalDeviceMirPresentationSupportKHR to resolve issue #1.<= /p>

  • Revision 3, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_mir_surface to VK_KHR_mir_surface.

  • Revision 4, 2015-11-28 (Daniel Rakos)

    • Updated the surface create function to take a pCreateInfo structure.

VK_KHR_push_descriptor

Name String

VK_KHR_push_descriptor

Extension Type

Device extension

Registered Extension Number

81

Revision

2

Extension and Version Dependencies
Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-09-12

IP Status

No known IP claims.

Contributors
  • Jeff Bolz, NVIDIA

  • Michael Worcester, Imagination Technologies

This extension allows descriptors to be written into the command buffer, while the implementation is responsible for managing their memory. Push descriptors may enable easier porting from older APIs and in some case= s can be more efficient than writing descriptors into descriptor sets.

New Object Types

None.

New Enum Constants

None.

Issues

None.

Examples

None.

Version History

  • Revision 1, 2016-10-15 (Jeff Bolz)

    • Internal revisions

  • Revision 2, 2017-09-12 (Tobias Hector)

    • Added interactions with Vulkan 1.1

VK_KHR_sampler_mirror_clamp_= to_edge

Name String

VK_KHR_sampler_mirror_clamp_to_edge

Extension Type

Device extension

Registered Extension Number

15

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Tobias Hector @tobski

Last Modified Date

2016-02-16

Contributors
  • Tobias Hector, Imagination Technologies

VK_KHR_sampler_mirror_clamp_to_edge extends the set of samp= ler address modes to include an additional mode (VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) that effectivel= y uses a texture map twice as large as the original image in which the additional half of the new image is a mirror image of the original image.

This new mode relaxes the need to generate images whose opposite edges m= atch by using the original image to generate a matching =E2=80=9Cmirror image=E2= =80=9D. This mode allows the texture to be mirrored only once in the negative s, t, and r directions.

New Enum Constants

Example

Creating a sampler with the new address mode in each dimension

    VkSamplerCreat=
eInfo createInfo =3D
    {
        VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO // sT=
ype
        // Other members set to application-desired=
 values
    };

    createInfo.addressModeU =3D VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDG=
E;
    createInfo.addressModeV =3D VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDG=
E;
    createInfo.addressModeW =3D VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDG=
E;

    VkSampler sampler;
    VkResult result =3D vkCreateSampler(
        device,
        &createInfo,
        &sampler);

Version History

  • Revision 1, 2016-02-16 (Tobias Hector)

    • Initial draft

VK_KHR_shared_presentable_image<= /h4>
Name String

VK_KHR_shared_presentable_image

Extension Type

Device extension

Registered Extension Number

112

Revision

1

Extension and Version Dependencies
Contact
  • Alon Or-bach @alonorbach

Last Modified Date

2017-03-20

IP Status

No known IP claims.

Contributors
  • Alon Or-bach, Samsung Electronics

  • Ian Elliott, Google

  • Jesse Hall, Google

  • Pablo Ceballos, Google

  • Chris Forbes, Google

  • Jeff Juliano, NVIDIA

  • James Jones, NVIDIA

  • Daniel Rakos, AMD

  • Tobias Hector, Imagination Technologies

  • Graham Connor, Imagination Technologies

  • Michael Worcester, Imagination Technologies

  • Cass Everitt, Oculus

  • Johannes Van Waveren, Oculus

This extension extends VK_KHR_swapchain to enable creation of a shared presentable image. This allows the application to use the image while the presention engine is accessing it, in order to reduce the latency between rendering and presentation.

New Object Types

None.

New Enum Constants

  • Extending VkPresentModeKHR:

    • VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR

    • VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR

  • Extending VkImageLayout:

    • VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR

New Enums

None.

New Functions

Issues

1) Should we allow a Vulkan WSI swapchain to toggle between normal usage= and shared presentation usage?

RESOLVED: No. WSI swapchains are typically recreated with new properties instead of havin= g their properties changed. This can also save resources, assuming that fewer images are needed for shared presentation, and assuming that most VR applications do not need to switch between normal and shared usage.

2) Should we have a query for determining how the presentation engine refresh is triggered?

RESOLVED: Yes. This is done via which presentation modes a surface supports.

3) Should the object representing a shared presentable image be an exten= sion of a VkSwapchainKHR or a separate object?

RESOLVED: Extension of a swapchain due to overlap in cr= eation properties and to allow common functionality between shared and normal presentable images and swapchains.

4) What should we call the extension and the new structures it creates?<= /p>

RESOLVED: Shared presentable image / shared present.

5) Should the minImageCount and presentMode va= lues of the VkSwapchainCreateInfoKHR be ignored, or requi= red to be compatible values?

RESOLVED: minImageCount must be set to 1, = and presentMode should be set to either VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR or VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR.

6) What should the layout of the shared presentable image be?

RESOLVED: After acquiring the shared presentable image,= the application must transition it to the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR l= ayout prior to it being used. After this intial transition, any image usage that was requested during swapchain creation can be performed on th= e image without layout transitions being performed.

7) Do we need a new API for the trigger to refresh new content?

RESOLVED: vkQueuePresentKHR to a= ct as API to trigger a refresh, as will allow combination with other compatible extensions to vkQueuePresentKHR.

8) How should an application detect a VK_ERROR_OUT_OF_DATE_KHR error on a swapchain using the VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KH= R present mode?

RESOLVED: Introduce vkGetSwapc= hainStatusKHR to allow applications to query the status of a swapchain using a shared presentation mode.

RESOLVED: State that implementations may use it as a hi= nt for updated content.

10) Can the ownership of a shared presentable image be transferred to a different queue?

RESOLVED: No. It is not possible to transfer ownership of a shared presentable image obtained from a swapchain created using VK_SHARING_MODE_EXCLUSIVE after it has been presented.

11) How should vkQueueSubmit behave if a command buff= er uses an image from an VK_ERROR_OUT_OF_DATE_KHR swapchain?

RESOLVED: vkQueueSubmit is expected = to return the VK_ERROR_DEVICE_LOST error.

12) Can Vulkan provide any guarantee on the order of rendering, to enabl= e beam chasing?

RESOLVED: This could be achieved via use of render pass= es to ensure strip rendering.

Version History

  • Revision 1, 2017-03-20 (Alon Or-bach)

    • Internal revisions

VK_KHR_surface

Name String

VK_KHR_surface

Extension Type

Instance extension

Registered Extension Number

1

Revision

25

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • James Jones @cubanismo

  • Ian Elliott @ianelliottus

Last Modified Date

2016-08-25

IP Status

No known IP claims.

Contributors
  • Patrick Doane, Blizzard

  • Ian Elliott, LunarG

  • Jesse Hall, Google

  • James Jones, NVIDIA

  • David Mao, AMD

  • Norbert Nopper, Freescale

  • Alon Or-bach, Samsung

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Jeff Vigil, Qualcomm

  • Chia-I Wu, LunarG

  • Jason Ekstrand, Intel

The VK_KHR_surface extension is an instance extension. It introduces VkSurfaceKHR objects, which abstract native= platform surface or window objects for use with Vulkan. It also provides a way to determine whether a queue family in a physical device supports presenting to particular surface.

Separate extensions for each platform provide the mechanisms for creatin= g VkSurfaceKHR objects, but once created they may be used i= n this and other platform-independent extensions, in particular the VK_KHR_swapchain extension.

New Object Types

New Enum Constants

  • Extending VkResult:

    • VK_ERROR_SURFACE_LOST_KHR

    • VK_ERROR_NATIVE_WINDOW_IN_USE_KHR

Examples

Note

The example code for the VK_KHR_surface and VK_KHR_swapchain extensions was removed from the appendix after revision 1.0.29. This WSI example code was ported to the cube demo that is shipped with the official Khronos SDK, and is being kept up-to-date in that location (see: https://github.com/KhronosGroup/Vulkan-Tools/blob/mast= er/cube/cube.c).

Issues

1) Should this extension include a method to query whether a physical de= vice supports presenting to a specific window or native surface on a given platform?

RESOLVED: Yes. Without this, applications would need to create a device instance to determine whether a particular window can be presented to. Knowing that a device supports presentation to a platform in general is not sufficient, as a single machine might support multiple seats, or instances of the platform that each use different underlying physical devices. Additionally, on some platforms, such as the X Window System, different drivers and devices might be used for different windows depending on which section of the desktop they exist on.

2) Should the vkGetPhysicalDe= viceSurfaceCapabilitiesKHR, vkGetPhysicalDeviceSurfaceFormatsKHR<= /a>, and vkGetPhysicalDeviceSurfacePresen= tModesKHR functions from VK_KHR_swapchain be modified to operate = on physical devices and moved to this extension to implement the resolution of issue 1?

RESOLVED: No, separate query functions are needed, as t= he purposes served are similar but incompatible. The vkGetPhysicalDeviceSurface*KHR functions return informatio= n that could potentially depend on an initialized device. For example, the formats supported for presentation to the surface might vary depending on which device extensions are enabled. The query introduced to resolve issue 1 should be used only to query generi= c driver or platform properties. The physical device parameter is intended to serve only as an identifier rather than a stateful object.

3) Should Vulkan include support Xlib or XCB as the API for accessing th= e X Window System platform?

RESOLVED: Both. XCB is a more modern and efficient API, but Xlib usage is deeply ingrained in many applications and likely will remain in use for the foreseeable future. Not all drivers necessarily need to support both, but including both as options in the core specification will probably encourage support, which should in turn ease adoption of the Vulkan API in older codebases. Additionally, the performance improvements possible with XCB likely will no= t have a measurable impact on the performance of Vulkan presentation and othe= r minimal window system interactions defined here.

4) Should the GBM platform be included in the list of platform enums?

RESOLVED: Deferred, and will be addressed with a platfo= rm-specific extension to be written in the future.

Version History

  • Revision 1, 2015-05-20 (James Jones)

    • Initial draft, based on LunarG KHR spec, other KHR specs, patches attached to bugs.

  • Revision 2, 2015-05-22 (Ian Elliott)

    • Created initial Description section.

    • Removed query for whether a platform requires the use of a queue for presentation, since it was decided that presentation will always be modeled as being part of the queue.

    • Fixed typos and other minor mistakes.

  • Revision 3, 2015-05-26 (Ian Elliott)

    • Improved the Description section.

  • Revision 4, 2015-05-27 (James Jones)

    • Fixed compilation errors in example code.

  • Revision 5, 2015-06-01 (James Jones)

    • Added issues 1 and 2 and made related spec updates.

  • Revision 6, 2015-06-01 (James Jones)

    • Merged the platform type mappings table previously removed from VK_KHR_swapchain with the platform description table in this spec.

    • Added issues 3 and 4 documenting choices made when building the initial list of native platforms supported.

  • Revision 7, 2015-06-11 (Ian Elliott)

    • Updated table 1 per input from the KHR TSG.

    • Updated issue 4 (GBM) per discussion with Daniel Stone. He will create a platform-specific extension sometime in the future.

  • Revision 8, 2015-06-17 (James Jones)

    • Updated enum-extending values using new convention.

    • Fixed the value of VK_SURFACE_PLATFORM_INFO_TYPE_SUPPORTED_KHR.

  • Revision 9, 2015-06-17 (James Jones)

    • Rebased on Vulkan API version 126.

  • Revision 10, 2015-06-18 (James Jones)

    • Marked issues 2 and 3 resolved.

  • Revision 11, 2015-06-23 (Ian Elliott)

    • Examples now show use of function pointers for extension functions.

    • Eliminated extraneous whitespace.

  • Revision 12, 2015-07-07 (Daniel Rakos)

    • Added error section describing when each error is expected to be reported.

    • Replaced the term "queue node index" with "queue family index" in the spec as that is the agreed term to be used in the latest version of the core header and spec.

    • Replaced bool32_t with VkBool32.

  • Revision 13, 2015-08-06 (Daniel Rakos)

    • Updated spec against latest core API header version.

  • Revision 14, 2015-08-20 (Ian Elliott)

    • Renamed this extension and all of its enumerations, types, functions, etc. This makes it compliant with the proposed standard for Vulkan extensions.

    • Switched from "revision" to "version", including use of the VK_MAKE_VERSION macro in the header file.

    • Did miscellaneous cleanup, etc.

  • Revision 15, 2015-08-20 (Ian Elliott=E2=80=94=E2=80=8Bporting a 2015-07-= 29 change from James Jones)

    • Moved the surface transform enums here from VK_WSI_swapchain so they could be re-used by VK_WSI_display.

  • Revision 16, 2015-09-01 (James Jones)

    • Restore single-field revision number.

  • Revision 17, 2015-09-01 (James Jones)

    • Fix example code compilation errors.

  • Revision 18, 2015-09-26 (Jesse Hall)

    • Replaced VkSurfaceDescriptionKHR with the VkSurfaceKHR object, which is created via layered extensions. Added VkDestroySurfaceKHR.

  • Revision 19, 2015-09-28 (Jesse Hall)

    • Renamed from VK_EXT_KHR_swapchain to VK_EXT_KHR_surface.

  • Revision 20, 2015-09-30 (Jeff Vigil)

    • Add error result VK_ERROR_SURFACE_LOST_KHR.

  • Revision 21, 2015-10-15 (Daniel Rakos)

    • Updated the resolution of issue #2 and include the surface capability queries in this extension.

    • Renamed SurfaceProperties to SurfaceCapabilities as it better reflects that the values returned are the capabilities of the surface on a particular device.

    • Other minor cleanup and consistency changes.

  • Revision 22, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_surface to VK_KHR_surface.

  • Revision 23, 2015-11-03 (Daniel Rakos)

    • Added allocation callbacks to vkDestroySurfaceKHR.

  • Revision 24, 2015-11-10 (Jesse Hall)

    • Removed VkSurfaceTransformKHR. Use VkSurfaceTransformFlagBitsKHR instead.

    • Rename VkSurfaceCapabilitiesKHR member maxImageArraySize to maxImageArrayLayers.

  • Revision 25, 2016-01-14 (James Jones)

    • Moved VK_ERROR_NATIVE_WINDOW_IN_USE_KHR from the VK_KHR_android_surface to the VK_KHR_surface extension.

  • 2016-08-23 (Ian Elliott)

    • Update the example code, to not have so many characters per line, and to split out a new example to show how to obtain function pointers.

  • 2016-08-25 (Ian Elliott)

    • A note was added at the beginning of the example code, stating that it will be removed from future versions of the appendix.

VK_KHR_swapchain

Name String

VK_KHR_swapchain

Extension Type

Device extension

Registered Extension Number

2

Revision

70

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

  • Ian Elliott @ianelliottus

Last Modified Date

2017-10-06

IP Status

No known IP claims.

Interactions and External Dependencies
  • Interacts with Vulkan 1.1

Contributors
  • Patrick Doane, Blizzard

  • Ian Elliott, LunarG

  • Jesse Hall, Google

  • Mathias Heyer, NVIDIA

  • James Jones, NVIDIA

  • David Mao, AMD

  • Norbert Nopper, Freescale

  • Alon Or-bach, Samsung

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Jeff Vigil, Qualcomm

  • Chia-I Wu, LunarG

  • Jason Ekstrand, Intel

  • Matthaeus G. Chajdas, AMD

  • Ray Smith, ARM

The VK_KHR_swapchain extension is the device-level companio= n to the VK_KHR_surface extension. It introduces VkSwapchainKHR objects, which provide the= ability to present rendering results to a surface.

New Object Types

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR

    • VK_STRUCTURE_TYPE_PRESENT_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR

    • VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR

    • VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR

    • VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR

  • Extending VkImageLayout:

    • VK_IMAGE_LAYOUT_PRESENT_SRC_KHR

  • Extending VkResult:

    • VK_SUBOPTIMAL_KHR

    • VK_ERROR_OUT_OF_DATE_KHR

Issues

1) Does this extension allow the application to specify the memory backi= ng of the presentable images?

RESOLVED: No. Unlike standard images, the implementation will allocate the memory backing of the presentable image.

2) What operations are allowed on presentable images?

RESOLVED: This is determined by the image usage flags s= pecified when creating the presentable image=E2=80=99s swapchain.

3) Does this extension support MSAA presentable images?

RESOLVED: No. Presentable images are always single-sampled. Multi-sampled rendering must use regular images. To present the rendering results the application must manually resolve the multi- sampled image to a single-sampled presentable image prior to presentation.

4) Does this extension support stereo/multi-view presentable images?

RESOLVED: Yes. The number of views associated with a presentable image is determined by th= e imageArrayLayers specified when creating a swapchain. All presentable images in a given swapchain use the same array size.

5) Are the layers of stereo presentable images half-sized?

RESOLVED: No. The image extents always match those requested by the application.

6) Do the =E2=80=9Cpresent=E2=80=9D and =E2=80=9Cacquire next image=E2= =80=9D commands operate on a queue? If not, do they need to include explicit semaphore objects to interlock them with queue operations?

RESOLVED: The present command operates on a queue. The image ownership operation it represents happens in order with other operations on the queue, so no explicit semaphore object is required to synchronize its actions.

Applications may want to acquire the next image in separate threads from those in which they manage their queue, or in multiple threads. To make such usage easier, the acquire next image command takes a semaphore to signal as a method of explicit synchronization. The application must later queue a wait for this semaphore before queuing execution of any commands using the image.

7) Does vkAcquireNextImageKHR block if no ima= ges are available?

RESOLVED: The command takes a timeout parameter. Special values for the timeout are 0, which makes the call a non-blocking operation, and UINT64_MAX, which blocks indefinitely. Values in between will block for up to the specified time. The call will return when an image becomes available or an error occurs. It may, but is not required to, return before the specified timeout expires if the swapchain becomes out of date.

8) Can multiple presents be queued using one vkQueueP= resentKHR call?

RESOLVED: Yes. VkPresentInfoKHR contains a list of swapchains and co= rresponding image indices that will be presented. When supported, all presentations queued with a single vkQueuePresentKHR call will be applied atomically as= one operation. The same swapchain must not appear in the list more than once. Later extensions may provide applications stronger guarantees of atomicity for such present operations, and/or allow them to query whether atomic presentation of a particular group of swapchains is possible.

9) How do the presentation and acquire next image functions notify the application the targeted surface has changed?

RESOLVED: Two new result codes are introduced for this = purpose:

  • VK_SUBOPTIMAL_KHR - Presentation will still succeed, subjec= t to the window resize behavior, but the swapchain is no longer configured optimally for the surface it targets. Applications should query updated surface information and recreate their swapchain at the next convenient opportunity.

  • VK_ERROR_OUT_OF_DATE_KHR - Failure. The swapchain is no longer compatible with the surface it targets. The application must query updated surface information and recreate the swapchain before presentation will succeed.

These can be returned by both vkAcquireNextImageK= HR and vkQueuePresentKHR.

10) Does the vkAcquireNextImageKHR command re= turn a semaphore to the application via an output parameter, or accept a semaphore to signal from the application as an object handle parameter?

RESOLVED: Accept a semaphore to signal as an object han= dle. This avoids the need to specify whether the application must destroy the semaphore or whether it is owned by the swapchain, and if the latter, what its lifetime is and whether it can be re-used for other operations once it is received from vkAcquireNextImageKHR.

11) What types of swapchain queuing behavior should be exposed? Options include swap interval specification, mailbox/most recent vs. FIFO queue management, targeting specific vertical blank intervals or absolute times for a given present operation, and probably others. For some of these, whether they are specified at swapchain creation time or as per-present parameters needs to be decided as well.

RESOLVED: The base swapchain extension will expose 3 po= ssible behaviors (of which, FIFO will always be supported):

  • Immediate present: Does not wait for vertical blanking period to update the current image, likely resulting in visible tearing. No internal queue is used. Present requests are applied immediately.

  • Mailbox queue: Waits for the next vertical blanking period to update the current image. No tearing should be observed. An internal single-entry queue is used to hold pending presentation requests. If the queue is full when a new presentation request is received, the new request replaces the existing entry, and any images associated with the prior entry become available for re-use by the application.

  • FIFO queue: Waits for the next vertical blanking period to update the current image. No tearing should be observed. An internal queue containing numSwapchainImages - 1 entries is used to hold pending presentation requests. New requests are appended to the end of the queue, and one request is removed from the beginning of the queue and processed during each vertical blanking period in which the queue is non-empty

Not all surfaces will support all of these modes, so the modes supported will be returned using a surface info query. All surfaces must support the FIFO queue mode. Applications must choose one of these modes up front when creating a swapchain. Switching modes can be accomplished by recreating the swapchain.

12) Can VK_PRESENT_MODE_MAILBOX_KHR provide non-blocking gu= arantees for vkAcquireNextImageKHR? If so, what is the pr= oper criteria?

RESOLVED: Yes. The difficulty is not immediately obvious here. Naively, if at least 3 images are requested, mailbox mode should always hav= e an image available for the application if the application does not own any images when the call to vkAcquireNextImageKHR wa= s made. However, some presentation engines may have more than one =E2=80=9Ccurrent= =E2=80=9D image, and would still need to block in some cases. The right requirement appears to be that if the application allocates the surface=E2=80=99s minimum number of images + 1 then it is guaranteed non-bl= ocking behavior when it does not currently own any images.

13) Is there a way to create and initialize a new swapchain for a surfac= e that has generated a VK_SUBOPTIMAL_KHR return code while still= using the old swapchain?

RESOLVED: Not as part of this specification. This could be useful to allow the application to create an =E2=80=9Coptimal= =E2=80=9D replacement swapchain and rebuild all its command buffers using it in a background thread at a low priority while continuing to use the =E2=80=9Csuboptimal=E2=80=9D swapchain in the main thread. It could probably use the same =E2=80=9Catomic replace=E2=80=9D semantics p= roposed for recreating direct-to-device swapchains without incurring a mode switch. However, after discussion, it was determined some platforms probably could not support concurrent swapchains for the same surface though, so this will be left out of the base KHR extensions. A future extension could add this for platforms where it is supported.

14) Should there be a special value for VkSurfaceCapabilitiesKHR::maxImageCount= to indicate there are no practical limits on the number of images in a swapchain?

RESOLVED: Yes. There where often be cases where there is no practical limit to the number of images in a swapchain other than the amount of available resources (I.e.= , memory) in the system. Trying to derive a hard limit from things like memory size is prone to failure. It is better in such cases to leave it to applications to figure such soft limits out via trial/failure iterations.

15) Should there be a special value for VkSurfaceCapabilitiesKHR::currentExtent= to indicate the size of the platform surface is undefined?

RESOLVED: Yes. On some platforms (Wayland, for example), the surface size is defined by th= e images presented to it rather than the other way around.

16) Should there be a special value for VkSurfaceCapabilitiesKHR::maxImageExten= t to indicate there is no practical limit on the surface size?

RESOLVED: No. It seems unlikely such a system would exist. 0 could be used to indicate the platform places no limits on the extents beyond those imposed by Vulkan for normal images, but this query could just as easily return those same limits, so a special =E2=80=9Cunlimited=E2=80= =9D value does not seem useful for this field.

17) How should surface rotation and mirroring be exposed to applications= ? How do they specify rotation and mirroring transforms applied prior to presentation?

RESOLVED: Applications can query both the supported and= current transforms of a surface. Both are specified relative to the device=E2=80=99s =E2=80=9Cnatural=E2=80= =9D display rotation and direction. The supported transforms indicates which orientations the presentation engine accepts images in. For example, a presentation engine that does not support transforming surfaces as part of presentation, and which is presenting to a surface that is displayed with a 90-degree rotation, would return only one supported transform bit: VK_SURFACE_TRANSFORM_ROT90_BIT_KHR. Applications must transform their rendering by the transform they specify when creating the swapchain in preTransform field.

18) Can surfaces ever not support VK_MIRROR_NONE? Can they = support vertical and horizontal mirroring simultaneously? Relatedly, should VK_MIRROR_NONE[_BIT] be zero, or bit one, and should applicati= ons be allowed to specify multiple pre and current mirror transform bits, or exactly one?

RESOLVED: Since some platforms may not support presenti= ng with a transform other than the native window=E2=80=99s current transform, and prerotation/m= irroring are specified relative to the device=E2=80=99s natural rotation and directi= on, rather than relative to the surface=E2=80=99s current rotation and directio= n, it is necessary to express lack of support for no mirroring. To allow this, the MIRROR_NONE enum must occupy a bit in the f= lags. Since MIRROR_NONE must be a bit in the bitmask rather than a b= itmask with no values set, allowing more than one bit to be set in the bitmask would make it possible to describe undefined transforms such as VK_MIRROR_NONE_BIT | VK_MIRROR_HORIZONTAL_BIT, or= a transform that includes both =E2=80=9Cno mirroring=E2=80=9D and =E2=80=9Chorizontal m= irroring=E2=80=9D simultaneously. Therefore, it is desirable to allow specifying all supported mirroring transforms using only one bit. The question then becomes, should there be a VK_MIRROR_HORIZONTAL_AND_VERTICAL_BIT to represent a simultane= ous horizontal and vertical mirror transform? However, such a transform is equivalent to a 180 degree rotation, so presentation engines and applications that wish to support or use such a transform can express it through rotation instead. Therefore, 3 exclusive bits are sufficient to express all needed mirroring transforms.

19) Should support for sRGB be required?

RESOLVED: In the advent of UHD and HDR display devices,= proper color space information is vital to the display pipeline represented by the swapchain. The app can discover the supported format/color-space pairs and select a pair most suited to its rendering needs. Currently only the sRGB color space is supported, future extensions may provide support for more color spaces. See issues 23 and 24.

20) Is there a mechanism to modify or replace an existing swapchain with= one targeting the same surface?

RESOLVED: Yes. This is described above in the text.

21) Should there be a way to set prerotation and mirroring using native = APIs when presenting using a Vulkan swapchain?

RESOLVED: Yes. The transforms that can be expressed in this extension are a subset of thos= e possible on native platforms. If a platform exposes a method to specify the transform of presented images for a given surface using native methods and exposes more transforms or other properties for surfaces than Vulkan supports, it might be impossible, difficult, or inconvenient to set some of those properties using Vulkan KHR extensions and some using the native interfaces. To avoid overwriting properties set using native commands when presenting using a Vulkan swapchain, the application can set the pretransform to =E2=80=9Cinherit=E2=80=9D, in which case the current native properties will= be used, or if none are available, a platform-specific default will be used. Platforms that do not specify a reasonable default or do not provide native mechanisms to specify such transforms should not include the inherit bits i= n the supportedTransforms bitmask they return in VkSurfaceCapabilitiesKHR.

22) Should the content of presentable images be clipped by objects obscu= ring their target surface?

RESOLVED: Applications can choose which behavior they p= refer. Allowing the content to be clipped could enable more optimal presentation methods on some platforms, but some applications might rely on the content of presentable images to perform techniques such as partial updates or motion blurs.

23) What is the purpose of specifying a VkColorSpaceKHR= along with VkFormat when creating a swapchain?

RESOLVED: While Vulkan itself is color space agnostic (= e.g. even the meaning of R, G, B and A can be freely defined by the rendering application), the swapchain eventually will have to present the images on a display device with specific color reproduction characteristics. If any color space transformations are necessary before an image can be displayed, the color space of the presented image must be known to the swapchain. A swapchain will only support a restricted set of color format and -space pairs. This set can be discovered via vkGetP= hysicalDeviceSurfaceFormatsKHR. As it can be expected that most display devices support the sRGB color space, at least one format/color-space pair has to be exposed, where the color space is VK_COLOR_SPACE_SRGB_NONLINEAR.

24) How are sRGB formats and the sRGB color space related?

RESOLVED: While Vulkan exposes a number of SRGB texture= formats, using such formats does not guarantee working in a specific color space. It merely means that the hardware can directly support applying the non-linear transfer functions defined by the sRGB standard color space when reading from or writing to images of that these formats. Still, it is unlikely that a swapchain will expose a *_SRGB fo= rmat along with any color space other than VK_COLOR_SPACE_SRGB_NONLINEAR.

On the other hand, non-*_SRGB formats will be very likely e= xposed in pair with a SRGB color space. This means, the hardware will not apply any transfer function when reading from or writing to such images, yet they will still be presented on a devic= e with sRGB display characteristics. In this case the application is responsible for applying the transfer function, for instance by using shader math.

25) How are the lifetime of surfaces and swapchains targeting them relat= ed?

RESOLVED: A surface must outlive any swapchains targeti= ng it. A VkSurfaceKHR owns the binding of the native window to t= he Vulkan driver.

26) How can the client control the way the alpha channel of swapchain im= ages is treated by the presentation engine during compositing?

RESOLVED: We should add new enum values to allow the cl= ient to negotiate with the presentation engine on how to treat image alpha values during the compositing process. Since not all platforms can practically control this through the Vulkan driver, a value of VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR is provi= ded like for surface transforms.

27) Is vkCreateSwapchainKHR the right function= to return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, or should the various platform-specific VkSurfaceKHR factory functions catch th= is error earlier?

RESOLVED: For most platforms, the VkSurfa= ceKHR structure is a simple container holding the data that identifies a native window or other object representing a surface on a particular platform. For the surface factory functions to return this error, they would likely need to register a reference on the native objects with the native display server somehow, and ensure no other such references exist. Surfaces were not intended to be that heavyweight.

Swapchains are intended to be the objects that directly manipulate nativ= e windows and communicate with the native presentation mechanisms. Swapchains will already need to communicate with the native display server to negotiate allocation and/or presentation of presentable images for a native surface. Therefore, it makes more sense for swapchain creation to be the point at which native object exclusivity is enforced. Platforms may choose to enforce further restrictions on the number of VkSurfaceKHR objects that may be created for the same nat= ive window if such a requirement makes sense on a particular platform, but a global requirement is only sensible at the swapchain level.

Examples

Note

The example code for the VK_KHR_surface= and VK_KHR_swapchain extensions was removed from the appendix after revision 1.0.29. This WSI example code was ported to the cube demo that is shipped with the official Khronos SDK, and is being kept up-to-date in that location (see: https://github.com/KhronosGroup/Vulkan-Tools/blob/mast= er/cube/cube.c).

Version History

  • Revision 1, 2015-05-20 (James Jones)

    • Initial draft, based on LunarG KHR spec, other KHR specs, patches attached to bugs.

  • Revision 2, 2015-05-22 (Ian Elliott)

    • Made many agreed-upon changes from 2015-05-21 KHR TSG meeting. This includes using only a queue for presentation, and having an explicit function to acquire the next image.

    • Fixed typos and other minor mistakes.

  • Revision 3, 2015-05-26 (Ian Elliott)

    • Improved the Description section.

    • Added or resolved issues that were found in improving the Description. For example, pSurfaceDescription is used consistently, instead of sometimes using pSurface.

  • Revision 4, 2015-05-27 (James Jones)

    • Fixed some grammatical errors and typos

    • Filled in the description of imageUseFlags when creating a swapchain.

    • Added a description of swapInterval.

    • Replaced the paragraph describing the order of operations on a queue for image ownership and presentation.

  • Revision 5, 2015-05-27 (James Jones)

    • Imported relevant issues from the (abandoned) vk_wsi_persistent_swapchain_images extension.

    • Added issues 6 and 7, regarding behavior of the acquire next image and present commands with respect to queues.

    • Updated spec language and examples to align with proposed resolutions to issues 6 and 7.

  • Revision 6, 2015-05-27 (James Jones)

    • Added issue 8, regarding atomic presentation of multiple swapchains

    • Updated spec language and examples to align with proposed resolution to issue 8.

  • Revision 7, 2015-05-27 (James Jones)

    • Fixed compilation errors in example code, and made related spec fixes.

  • Revision 8, 2015-05-27 (James Jones)

    • Added issue 9, and the related VK_SUBOPTIMAL_KHR result code.

    • Renamed VK_OUT_OF_DATE_KHR to VK_ERROR_OUT_OF_DATE_KHR.

  • Revision 9, 2015-05-27 (James Jones)

    • Added inline proposed resolutions (marked with [JRJ]) to some XXX questions/issues. These should be moved to the issues section in a subsequent update if the proposals are adopted.

  • Revision 10, 2015-05-28 (James Jones)

    • Converted vkAcquireNextImageKHR back to a non-queue operation that uses a VkSemaphore object for explicit synchronization.

    • Added issue 10 to determine whether vkAcquireNextImageKHR generates or returns semaphores, or whether it operates on a semaphore provided by the application.

  • Revision 11, 2015-05-28 (James Jones)

    • Marked issues 6, 7, and 8 resolved.

    • Renamed VkSurfaceCapabilityPropertiesKHR to VkSurfacePropertiesKHR to better convey the mutable nature of the info it contains.

  • Revision 12, 2015-05-28 (James Jones)

    • Added issue 11 with a proposed resolution, and the related issue 12.

    • Updated various sections of the spec to match the proposed resolution to issue 11.

  • Revision 13, 2015-06-01 (James Jones)

    • Moved some structures to VK_EXT_KHR_swap_chain to resolve the spec=E2=80= =99s issues 1 and 2.

  • Revision 14, 2015-06-01 (James Jones)

    • Added code for example 4 demonstrating how an application might make use of the two different present and acquire next image KHR result codes.

    • Added issue 13.

  • Revision 15, 2015-06-01 (James Jones)

    • Added issues 14 - 16 and related spec language.

    • Fixed some spelling errors.

    • Added language describing the meaningful return values for vkAcquireNextImageKHR and vkQueuePresentKHR.

  • Revision 16, 2015-06-02 (James Jones)

    • Added issues 17 and 18, as well as related spec language.

    • Removed some erroneous text added by mistake in the last update.

  • Revision 17, 2015-06-15 (Ian Elliott)

    • Changed special value from "-1" to "0" so that the data types can be unsigned.

  • Revision 18, 2015-06-15 (Ian Elliott)

    • Clarified the values of VkSurfacePropertiesKHR::minImageCount and the timeout parameter of the vkAcquireNextImageKHR function.

  • Revision 19, 2015-06-17 (James Jones)

    • Misc. cleanup. Removed resolved inline issues and fixed typos.

    • Fixed clarification of VkSurfacePropertiesKHR::minImageCount made in version 18.

    • Added a brief "Image Ownership" definition to the list of terms used in the spec.

  • Revision 20, 2015-06-17 (James Jones)

    • Updated enum-extending values using new convention.

  • Revision 21, 2015-06-17 (James Jones)

    • Added language describing how to use VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR.

    • Cleaned up an XXX comment regarding the description of which queues vkQueuePresentKHR can be used on.

  • Revision 22, 2015-06-17 (James Jones)

    • Rebased on Vulkan API version 126.

  • Revision 23, 2015-06-18 (James Jones)

    • Updated language for issue 12 to read as a proposed resolution.

    • Marked issues 11, 12, 13, 16, and 17 resolved.

    • Temporarily added links to the relevant bugs under the remaining unresolved issues.

    • Added issues 19 and 20 as well as proposed resolutions.

  • Revision 24, 2015-06-19 (Ian Elliott)

    • Changed special value for VkSurfacePropertiesKHR::currentExtent back to "-1" from "0". This value will never need to be unsigned, and "0" is actually a legal value.

  • Revision 25, 2015-06-23 (Ian Elliott)

    • Examples now show use of function pointers for extension functions.

    • Eliminated extraneous whitespace.

  • Revision 26, 2015-06-25 (Ian Elliott)

    • Resolved Issues 9 & 10 per KHR TSG meeting.

  • Revision 27, 2015-06-25 (James Jones)

    • Added oldSwapchain member to VkSwapchainCreateInfoKHR.

  • Revision 28, 2015-06-25 (James Jones)

    • Added the "inherit" bits to the rotation and mirroring flags and the associated issue 21.

  • Revision 29, 2015-06-25 (James Jones)

    • Added the "clipped" flag to VkSwapchainCreateInfoKHR, and the associated issue 22.

    • Specified that presenting an image does not modify it.

  • Revision 30, 2015-06-25 (James Jones)

    • Added language to the spec that clarifies the behavior of vkCreateSwapchainKHR() when the oldSwapchain field of VkSwapchainCreateInfoKHR is not NULL.

  • Revision 31, 2015-06-26 (Ian Elliott)

    • Example of new VkSwapchainCreateInfoKHR members, "oldSwapchain" and "clipped".

    • Example of using VkSurfacePropertiesKHR::{min|max}ImageCount to set VkSwapchainCreateInfoKHR::minImageCount.

    • Rename vkGetSurfaceInfoKHR()'s 4th parameter to "pDataSize", for consistency with other functions.

    • Add macro with C-string name of extension (just to header file).

  • Revision 32, 2015-06-26 (James Jones)

    • Minor adjustments to the language describing the behavior of "oldSwapchain"

    • Fixed the version date on my previous two updates.

  • Revision 33, 2015-06-26 (Jesse Hall)

    • Add usage flags to VkSwapchainCreateInfoKHR

  • Revision 34, 2015-06-26 (Ian Elliott)

    • Rename vkQueuePresentKHR()'s 2nd parameter to "pPresentInfo", for consistency with other functions.

  • Revision 35, 2015-06-26 (Jason Ekstrand)

    • Merged the VkRotationFlagBitsKHR and VkMirrorFlagBitsKHR enums into a single VkSurfaceTransformFlagBitsKHR enum.

  • Revision 36, 2015-06-26 (Jason Ekstrand)

    • Added a VkSurfaceTransformKHR enum that is not a bitmask. Each value in VkSurfaceTransformKHR corresponds directly to one of the bits in VkSurfaceTransformFlagBitsKHR so transforming from one to the other is easy. Having a separate enum means that currentTransform and preTransform are now unambiguous by definition.

  • Revision 37, 2015-06-29 (Ian Elliott)

    • Corrected one of the signatures of vkAcquireNextImageKHR, which had the last two parameters switched from what it is elsewhere in the specification and header files.

  • Revision 38, 2015-06-30 (Ian Elliott)

    • Corrected a typo in description of the vkGetSwapchainInfoKHR() function.

    • Corrected a typo in header file comment for VkPresentInfoKHR::sType.

  • Revision 39, 2015-07-07 (Daniel Rakos)

    • Added error section describing when each error is expected to be reported.

    • Replaced bool32_t with VkBool32.

  • Revision 40, 2015-07-10 (Ian Elliott)

    • Updated to work with version 138 of the "vulkan.h" header. This includes declaring the VkSwapchainKHR type using the new VK_DEFINE_NONDISP_HANDLE macro, and no longer extending VkObjectType (which was eliminated).

  • Revision 41 2015-07-09 (Mathias Heyer)

    • Added color space language.

  • Revision 42, 2015-07-10 (Daniel Rakos)

    • Updated query mechanism to reflect the convention changes done in the core spec.

    • Removed "queue" from the name of VK_STRUCTURE_TYPE_QUEUE_PRESENT_INFO_KHR to be consistent with the established naming convention.

    • Removed reference to the no longer existing VkObjectType enum.

  • Revision 43, 2015-07-17 (Daniel Rakos)

    • Added support for concurrent sharing of swapchain images across queue families.

    • Updated sample code based on recent changes

  • Revision 44, 2015-07-27 (Ian Elliott)

    • Noted that support for VK_PRESENT_MODE_FIFO_KHR is required. That is ICDs may optionally support IMMEDIATE and MAILBOX, but must support FIFO.

  • Revision 45, 2015-08-07 (Ian Elliott)

    • Corrected a typo in spec file (type and variable name had wrong case for the imageColorSpace member of the VkSwapchainCreateInfoKHR struct).

    • Corrected a typo in header file (last parameter in PFN_vkGetSurfacePropertiesKHR was missing "KHR" at the end of type: VkSurfacePropertiesKHR).

  • Revision 46, 2015-08-20 (Ian Elliott)

    • Renamed this extension and all of its enumerations, types, functions, etc. This makes it compliant with the proposed standard for Vulkan extensions.

    • Switched from "revision" to "version", including use of the VK_MAKE_VERSION macro in the header file.

    • Made improvements to several descriptions.

    • Changed the status of several issues from PROPOSED to RESOLVED, leaving no unresolved issues.

    • Resolved several TODOs, did miscellaneous cleanup, etc.

  • Revision 47, 2015-08-20 (Ian Elliott=E2=80=94=E2=80=8Bporting a 2015-07-= 29 change from James Jones)

    • Moved the surface transform enums to VK_WSI_swapchain so they could be re-used by VK_WSI_display.

  • Revision 48, 2015-09-01 (James Jones)

    • Various minor cleanups.

  • Revision 49, 2015-09-01 (James Jones)

    • Restore single-field revision number.

  • Revision 50, 2015-09-01 (James Jones)

    • Update Example #4 to include code that illustrates how to use the oldSwapchain field.

  • Revision 51, 2015-09-01 (James Jones)

    • Fix example code compilation errors.

  • Revision 52, 2015-09-08 (Matthaeus G. Chajdas)

    • Corrected a typo.

  • Revision 53, 2015-09-10 (Alon Or-bach)

    • Removed underscore from SWAP_CHAIN left in VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR.

  • Revision 54, 2015-09-11 (Jesse Hall)

    • Described the execution and memory coherence requirements for image transitions to and from VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR.

  • Revision 55, 2015-09-11 (Ray Smith)

    • Added errors for destroying and binding memory to presentable images

  • Revision 56, 2015-09-18 (James Jones)

    • Added fence argument to vkAcquireNextImageKHR

    • Added example of how to meter a host thread based on presentation rate.<= /p>

  • Revision 57, 2015-09-26 (Jesse Hall)

    • Replace VkSurfaceDescriptionKHR with VkSurfaceKHR.

    • Added issue 25 with agreed resolution.

  • Revision 58, 2015-09-28 (Jesse Hall)

    • Renamed from VK_EXT_KHR_device_swapchain to VK_EXT_KHR_swapchain.

  • Revision 59, 2015-09-29 (Ian Elliott)

    • Changed vkDestroySwapchainKHR() to return void.

  • Revision 60, 2015-10-01 (Jeff Vigil)

    • Added error result VK_ERROR_SURFACE_LOST_KHR.

  • Revision 61, 2015-10-05 (Jason Ekstrand)

    • Added the VkCompositeAlpha enum and corresponding structure fields.

  • Revision 62, 2015-10-12 (Daniel Rakos)

    • Added VK_PRESENT_MODE_FIFO_RELAXED_KHR.

  • Revision 63, 2015-10-15 (Daniel Rakos)

    • Moved surface capability queries to VK_EXT_KHR_surface.

  • Revision 64, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_swapchain to VK_KHR_swapchain.

  • Revision 65, 2015-10-28 (Ian Elliott)

    • Added optional pResult member to VkPresentInfoKHR, so that per-swapchain results can be obtained from vkQueuePresentKHR().

  • Revision 66, 2015-11-03 (Daniel Rakos)

    • Added allocation callbacks to create and destroy functions.

    • Updated resource transition language.

    • Updated sample code.

  • Revision 67, 2015-11-10 (Jesse Hall)

    • Add reserved flags bitmask to VkSwapchainCreateInfoKHR.

    • Modify naming and member ordering to match API style conventions, and so the VkSwapchainCreateInfoKHR image property members mirror corresponding VkImageCreateInfo members but with an 'image' prefix.

    • Make VkPresentInfoKHR::pResults non-const; it is an output array parameter.

    • Make pPresentInfo parameter to vkQueuePresentKHR const.

  • Revision 68, 2016-04-05 (Ian Elliott)

    • Moved the "validity" include for vkAcquireNextImage to be in its proper place, after the prototype and list of parameters.

    • Clarified language about presentable images, including how they are acquired, when applications can and cannot use them, etc. As part of this, removed language about "ownership" of presentable images, and replaced it with more-consistent language about presentable images being "acquired" by the application.

  • 2016-08-23 (Ian Elliott)

    • Update the example code, to use the final API command names, to not have so many characters per line, and to split out a new example to show how to obtain function pointers. This code is more similar to the LunarG "cube" demo program.

  • 2016-08-25 (Ian Elliott)

    • A note was added at the beginning of the example code, stating that it will be removed from future versions of the appendix.

  • Revision 69, 2017-09-07 (Tobias Hector)

    • Added interactions with Vulkan 1.1

  • Revision 70, 2017-10-06 (Ian Elliott)

    • Corrected interactions with Vulkan 1.1

VK_KHR_wayland_surface

Name String

VK_KHR_wayland_surface

Extension Type

Instance extension

Registered Extension Number

7

Revision

6

Extension and Version Dependencies
Contact
  • Jesse Hall @critsec

  • Ian Elliott @ianelliottus

Last Modified Date

2015-11-28

IP Status

No known IP claims.

Contributors
  • Patrick Doane, Blizzard

  • Jason Ekstrand, Intel

  • Ian Elliott, LunarG

  • Courtney Goeltzenleuchter, LunarG

  • Jesse Hall, Google

  • James Jones, NVIDIA

  • Antoine Labour, Google

  • Jon Leech, Khronos

  • David Mao, AMD

  • Norbert Nopper, Freescale

  • Alon Or-bach, Samsung

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Ray Smith, ARM

  • Jeff Vigil, Qualcomm

  • Chia-I Wu, LunarG

The VK_KHR_wayland_surface extension is an instance extensi= on. It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) that refers = to a Wayland wl_surface, as well as a query to determine support for render= ing to a Wayland compositor.

New Object Types

None

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR

New Enums

None

Issues

1) Does Wayland need a way to query for compatibility between a particul= ar physical device and a specific Wayland display? This would be a more genera= l query than vkGetPhysicalDeviceSurface= SupportKHR: if the Wayland-specific query returned VK_TRUE for a (VkPhysicalDevice, struct wl_display*) pair, then the physical device could be as= sumed to support presentation to any VkSurfaceKHR for surfaces on = the display.

RESOLVED: Yes. vkGetPhysicalDeviceWaylan= dPresentationSupportKHR was added to address this issue.

2) Should we require surfaces created with vk= CreateWaylandSurfaceKHR to support the VK_PRESENT_MODE_MAILBOX_KHR present mode?

RESOLVED: Yes. Wayland is an inherently mailbox window system and mailbox support is required for some Wayland compositor interactions to work as expected. While handling these interactions may be possible with VK_PRESENT_MODE_FIFO_KHR, it is much more difficult to do with= out deadlock and requiring all Wayland applications to be able to support implementations which only support VK_PRESENT_MODE_FIFO_KHR wo= uld be an onerous restriction on application developers.

Version History

  • Revision 1, 2015-09-23 (Jesse Hall)

    • Initial draft, based on the previous contents of VK_EXT_KHR_swapchain (later renamed VK_EXT_KHR_surface).

  • Revision 2, 2015-10-02 (James Jones)

    • Added vkGetPhysicalDeviceWaylandPresentationSupportKHR() to resolve issue #1.

    • Adjusted wording of issue #1 to match the agreed-upon solution.

    • Renamed "window" parameters to "surface" to match Wayland conventions.

  • Revision 3, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_wayland_surface to VK_KHR_wayland_surface.

  • Revision 4, 2015-11-03 (Daniel Rakos)

    • Added allocation callbacks to vkCreateWaylandSurfaceKHR.

  • Revision 5, 2015-11-28 (Daniel Rakos)

    • Updated the surface create function to take a pCreateInfo structure.

  • Revision 6, 2017-02-08 (Jason Ekstrand)

    • Added the requirement that implementations support VK_PRESENT_MODE_MAILBOX_KHR.

    • Added wording about interactions between vkQueuePrese= ntKHR and the Wayland requests sent to the compositor.

VK_KHR_win32_keyed_mutex

Name String

VK_KHR_win32_keyed_mutex

Extension Type

Device extension

Registered Extension Number

76

Revision

1

Extension and Version Dependencies
Contact
  • Carsten Rohde @crohde

Last Modified Date

2016-10-21

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Jeff Juliano, NVIDIA

  • Carsten Rohde, NVIDIA

Applications that wish to import Direct3D 11 memory objects into the Vul= kan API may wish to use the native keyed mutex mechanism to synchronize access to the memory between Vulkan and Direct3D. This extension provides a way for an application to access the keyed mutex associated with an imported Vulkan memory object when submitting command buffers to a queue.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR

New Enums

None.

New Functions

None.

Issues

None.

VK_KHR_win32_surface

Name String

VK_KHR_win32_surface

Extension Type

Instance extension

Registered Extension Number

10

Revision

6

Extension and Version Dependencies
Contact
  • Jesse Hall @critsec

  • Ian Elliott @ianelliottus

Last Modified Date

2017-04-24

IP Status

No known IP claims.

Contributors
  • Patrick Doane, Blizzard

  • Jason Ekstrand, Intel

  • Ian Elliott, LunarG

  • Courtney Goeltzenleuchter, LunarG

  • Jesse Hall, Google

  • James Jones, NVIDIA

  • Antoine Labour, Google

  • Jon Leech, Khronos

  • David Mao, AMD

  • Norbert Nopper, Freescale

  • Alon Or-bach, Samsung

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Ray Smith, ARM

  • Jeff Vigil, Qualcomm

  • Chia-I Wu, LunarG

The VK_KHR_win32_surface extension is an instance extension= . It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) that refers = to a Win32 HWND, as well as a query to determine support for rendering to the windows desktop.<= /p>

New Object Types

None

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR

New Enums

None

Issues

1) Does Win32 need a way to query for compatibility between a particular physical device and a specific screen? Compatibility between a physical device and a window generally only depends on what screen the window is on. However, there is not an obvious way to identify a screen without already having a window on the screen.

RESOLVED: No. While it may be useful, there is not a clear way to do this on Win32. However, a method was added to query support for presenting to the windows desktop as a whole.

2) If a native window object (HWND) is used by one graphics= API, and then is later used by a different graphics API (one of which is Vulkan), ca= n these uses interfere with each other?

RESOLVED: Yes.

Uses of a window object by multiple graphics APIs results in undefined behavior. Such behavior may succeed when using one Vulkan implementation but fail whe= n using a different Vulkan implementation. Potential failures include:

  • Creating then destroying a flip presentation model DXGI swapchain on a window object can prevent vkCreateSwapchainKHR fr= om succeeding on the same window object.

  • Creating then destroying a VkSwapchainKHR on a windo= w object can prevent creation of a bitblt model DXGI swapchain on the same window object.

  • Creating then destroying a VkSwapchainKHR on a windo= w object can effectively SetPixelFormat to a different format than the form= at chosen by an OpenGL application.

  • Creating then destroying a VkSwapchainKHR on a windo= w object on one VkPhysicalDevice can prevent vk= CreateSwapchainKHR from succeeding on the same window object, but on a different VkPhysicalDevice that is associated with a different = Vulkan ICD.

In all cases the problem can be worked around by creating a new window object.

Technical details include:

  • Creating a DXGI swapchain over a window object can alter the object for the remainder of its lifetime. The alteration persists even after the DXGI swapchain has been destroyed. This alteration can make it impossible for a conformant Vulkan implementation to create a VkSwapchainKHR over the same= window object. Mention of this alteration can be found in the remarks section of the MSDN documentation for DXGI_SWAP_EFFECT.

  • Calling GDI=E2=80=99s SetPixelFormat (needed by OpenGL=E2= =80=99s WGL layer) on a window object alters the object for the remainder of its lifetime. The MSDN documentation for SetPixelFormat explains that a wind= ow object=E2=80=99s pixel format can be set only one time.

  • Creating a VkSwapchainKHR over a window object can a= lter the object for the remaining life of its lifetime. Either of the above alterations may occur as a side-effect of VkSwapchainKHR.

Version History

  • Revision 1, 2015-09-23 (Jesse Hall)

    • Initial draft, based on the previous contents of VK_EXT_KHR_swapchain (later renamed VK_EXT_KHR_surface).

  • Revision 2, 2015-10-02 (James Jones)

    • Added presentation support query for win32 desktops.

  • Revision 3, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_win32_surface to VK_KHR_win32_surface.

  • Revision 4, 2015-11-03 (Daniel Rakos)

    • Added allocation callbacks to vkCreateWin32SurfaceKHR.

  • Revision 5, 2015-11-28 (Daniel Rakos)

    • Updated the surface create function to take a pCreateInfo structure.

  • Revision 6, 2017-04-24 (Jeff Juliano)

    • Add issue 2 addressing reuse of a native window object in a different Graphics API, or by a different Vulkan ICD.

VK_KHR_xcb_surface

Name String

VK_KHR_xcb_surface

Extension Type

Instance extension

Registered Extension Number

6

Revision

6

Extension and Version Dependencies
Contact
  • Jesse Hall @critsec

  • Ian Elliott @ianelliottus

Last Modified Date

2015-11-28

IP Status

No known IP claims.

Contributors
  • Patrick Doane, Blizzard

  • Jason Ekstrand, Intel

  • Ian Elliott, LunarG

  • Courtney Goeltzenleuchter, LunarG

  • Jesse Hall, Google

  • James Jones, NVIDIA

  • Antoine Labour, Google

  • Jon Leech, Khronos

  • David Mao, AMD

  • Norbert Nopper, Freescale

  • Alon Or-bach, Samsung

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Ray Smith, ARM

  • Jeff Vigil, Qualcomm

  • Chia-I Wu, LunarG

The VK_KHR_xcb_surface extension is an instance extension. It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) that refers = to an X11 Window, using the XCB client-side library, as well as a query to determine support for rendering via XCB.

New Object Types

None

New Enum Constants

New Enums

None

New Structures

Issues

1) Does XCB need a way to query for compatibility between a particular physical device and a specific screen? This would be a more general query than vkGetPhysicalDeviceSurfaceSuppor= tKHR: If it returned VK_TRUE, then the physical device could be assumed to support presentation to any window on that screen.

RESOLVED: Yes, this is needed for toolkits that want to= create a VkDevice before creating a window. To ensure the query is reliable, it must be made against a particular X visual rather than the screen in general.

Version History

  • Revision 1, 2015-09-23 (Jesse Hall)

    • Initial draft, based on the previous contents of VK_EXT_KHR_swapchain (later renamed VK_EXT_KHR_surface).

  • Revision 2, 2015-10-02 (James Jones)

    • Added presentation support query for an (xcb_connection_t*, xcb_visualid_t) pair.

    • Removed "root" parameter from CreateXcbSurfaceKHR(), as it is redundant when a window on the same screen is specified as well.

    • Adjusted wording of issue #1 and added agreed upon resolution.

  • Revision 3, 2015-10-14 (Ian Elliott)

    • Removed "root" parameter from CreateXcbSurfaceKHR() in one more place.

  • Revision 4, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_xcb_surface to VK_KHR_xcb_surface.

  • Revision 5, 2015-10-23 (Daniel Rakos)

    • Added allocation callbacks to vkCreateXcbSurfaceKHR.

  • Revision 6, 2015-11-28 (Daniel Rakos)

    • Updated the surface create function to take a pCreateInfo structure.

VK_KHR_xlib_surface

Name String

VK_KHR_xlib_surface

Extension Type

Instance extension

Registered Extension Number

5

Revision

6

Extension and Version Dependencies
Contact
  • Jesse Hall @critsec

  • Ian Elliott @ianelliottus

Last Modified Date

2015-11-28

IP Status

No known IP claims.

Contributors
  • Patrick Doane, Blizzard

  • Jason Ekstrand, Intel

  • Ian Elliott, LunarG

  • Courtney Goeltzenleuchter, LunarG

  • Jesse Hall, Google

  • James Jones, NVIDIA

  • Antoine Labour, Google

  • Jon Leech, Khronos

  • David Mao, AMD

  • Norbert Nopper, Freescale

  • Alon Or-bach, Samsung

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Ray Smith, ARM

  • Jeff Vigil, Qualcomm

  • Chia-I Wu, LunarG

The VK_KHR_xlib_surface extension is an instance extension. It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) that refers = to an X11 Window, using the Xlib client-side library, as well as a query to determine support for rendering via Xlib.

New Object Types

None

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR

New Enums

None

Issues

1) Does X11 need a way to query for compatibility between a particular physical device and a specific screen? This would be a more general query than vkGetPhysicalDeviceSurfaceSuppor= tKHR : if it returned VK_TRUE, then the physical device could be assumed to support presentation to any window on that screen.

RESOLVED: Yes, this is needed for toolkits that want to= create a VkDevice before creating a window. To ensure the query is reliable, it must be made against a particular X visual rather than the screen in general.

Version History

  • Revision 1, 2015-09-23 (Jesse Hall)

    • Initial draft, based on the previous contents of VK_EXT_KHR_swapchain (later renamed VK_EXT_KHR_surface).

  • Revision 2, 2015-10-02 (James Jones)

    • Added presentation support query for (Display*, VisualID) pair.

    • Removed "root" parameter from CreateXlibSurfaceKHR(), as it is redundant when a window on the same screen is specified as well.

    • Added appropriate X errors.

    • Adjusted wording of issue #1 and added agreed upon resolution.

  • Revision 3, 2015-10-14 (Ian Elliott)

    • Renamed this extension from VK_EXT_KHR_x11_surface to VK_EXT_KHR_xlib_surface.

  • Revision 4, 2015-10-26 (Ian Elliott)

    • Renamed from VK_EXT_KHR_xlib_surface to VK_KHR_xlib_surface.

  • Revision 5, 2015-11-03 (Daniel Rakos)

    • Added allocation callbacks to vkCreateXlibSurfaceKHR.

  • Revision 6, 2015-11-28 (Daniel Rakos)

    • Updated the surface create function to take a pCreateInfo structure.

New Enum Constants

None.

New Enums

None.

New Structures

None.

Issues

1) Should vkAcquireXlibDisplayEXT take an R= andR display ID, or a Vulkan display handle as input?

RESOLVED: A Vulkan display handle. Otherwise there would be no way to specify handles to displays that had bee= n =E2=80=9Cblacklisted=E2=80=9D or prevented from being included in the X11 d= isplay list by some native platform or vendor-specific mechanism.

2) How does an application figure out which RandR display corresponds to= a Vulkan display?

RESOLVED: A new function, v= kGetRandROutputDisplayEXT, is introduced for this purpose.

3) Should vkGetRandROutputDisplayEXT be = part of this extension, or a general Vulkan + RandR or Vulkan + Xlib extension?

RESOLVED: To avoid yet another extension, include it in= this extension.

Version History

  • Revision 1, 2016-12-13 (James Jones)

    • Initial draft

VK_EXT_blend_operation_advanced<= /h4>
Name String

VK_EXT_blend_operation_advanced

Extension Type

Device extension

Registered Extension Number

149

Revision

2

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-06-12

Contributors
  • Jeff Bolz, NVIDIA

This extension adds a number of =E2=80=9Cadvanced=E2=80=9D blending oper= ations that can be used to perform new color blending operations, many of which are more complex than the standard blend modes provided by unextended Vulkan. This extension requires different styles of usage, depending on the level o= f hardware support and the enabled features:

  • If VkPhysicalDeviceBlendOpe= rationAdvancedFeaturesEXT::advancedBlendCoherentOperations is VK_FALSE, the new blending operations are supported, but a memory dependency must separate each adva= nced blend operation on a given sample. VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT is used to synchronize reads using advanced blend operations.

  • If VkPhysicalDeviceBlendOpe= rationAdvancedFeaturesEXT::advancedBlendCoherentOperations is VK_TRUE, advanced blend operations obey primitive order jus= t like basic blend operations.

In unextended Vulkan, the set of blending operations is limited, and can be expressed very simply. The VK_BLEND_OP_MIN and VK_BLEND_OP_MAX blend ope= rations simply compute component-wise minimums or maximums of source and destination color components. The VK_BLEND_OP_ADD, VK_BLEND_OP_SUBTRACT, and VK_BLEND_OP_REVERSE_SUBTRACT modes multiply the source and des= tination colors by source and destination factors and either add the two products together or subtract one from the other. This limited set of operations supports many common blending operations but precludes the use of more sophisticated transparency and blending operation= s commonly available in many dedicated imaging APIs.

This extension provides a number of new =E2=80=9Cadvanced=E2=80=9D blend= ing operations. Unlike traditional blending operations using VK_BLEND_OP_ADD, = these blending equations do not use source and destination factors specified by VkBlendFactor. Instead, each blend operation specifies a complete equation based on the source and destination colors. These new blend operations are used for both RGB and alpha components; they must not be used to perform separate RGB = and alpha blending (via different values of color and alpha VkBlendOp).

These blending operations are performed using premultiplied colors, wher= e RGB colors can be considered premultiplie= d or non-premultiplied by alpha, according to the srcPremultiplied and dstPremultiplied members of VkPipelineColorBlendAdva= ncedStateCreateInfoEXT. If a color is considered non-premultiplied, the (R,G,B) color components ar= e multiplied by the alpha component prior to blending. For non-premultiplied color components in the range [0,1= ], the corresponding premultiplied color component would have values in the range [0 =C3=97 A, 1 =C3=97 A].

Many of these advanced blending equations are formulated where the resul= t of blending source and destination colors with partial coverage have three separate contributions: from the portions covered by both the source and th= e destination, from the portion covered only by the source, and from the portion covered only by the destination. The blend parameter VkPipelineColorBlendAdvance= dStateCreateInfoEXT::blendOverlap can be used to specify a correlation betw= een source and destination pixel coverage. If set to VK_BLEND_OVERLAP_CONJOINT_EXT, the source and destin= ation are considered to have maximal overlap, as would be the case if drawing two objects on top of each other. If set to VK_BLEND_OVERLAP_DISJOINT_EXT, the source and destin= ation are considered to have minimal overlap, as would be the case when rendering a complex polygon tessellated into individual non-intersecting triangles. If set to VK_BLEND_OVERLAP_UNCORRELATED_EXT, the source and destination coverage are assumed to have no spatial correlation within the pixel.

In addition to the coherency issues on implementations not supporting advancedBlendCoherentOperations, this extension has several limitations worth noting. First, the new blend operations have a limit on the number of color attachments they can be used with, as ind= icated by VkPhysicalDeviceBlendO= perationAdvancedPropertiesEXT::advancedBlendMaxColorAttachments. Additionally, blending precision may be l= imited to 16-bit floating-point, which may result in a loss of precision a= nd dynamic range for framebuffer formats with 32-bit floating-point components, and in a loss of precision for formats with 12- and 16-bit signed or unsigned normalized integer components.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURE= S_EXT

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERT= IES_EXT

    • VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_= EXT

  • Extending VkAccessFlagBits:

    • VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT

  • Extending VkBlendOp:

    • VK_BLEND_OP_ZERO_EXT

    • VK_BLEND_OP_SRC_EXT

    • VK_BLEND_OP_DST_EXT

    • VK_BLEND_OP_SRC_OVER_EXT

    • VK_BLEND_OP_DST_OVER_EXT

    • VK_BLEND_OP_SRC_IN_EXT

    • VK_BLEND_OP_DST_IN_EXT

    • VK_BLEND_OP_SRC_OUT_EXT

    • VK_BLEND_OP_DST_OUT_EXT

    • VK_BLEND_OP_SRC_ATOP_EXT

    • VK_BLEND_OP_DST_ATOP_EXT

    • VK_BLEND_OP_XOR_EXT

    • VK_BLEND_OP_MULTIPLY_EXT

    • VK_BLEND_OP_SCREEN_EXT

    • VK_BLEND_OP_OVERLAY_EXT

    • VK_BLEND_OP_DARKEN_EXT

    • VK_BLEND_OP_LIGHTEN_EXT

    • VK_BLEND_OP_COLORDODGE_EXT

    • VK_BLEND_OP_COLORBURN_EXT

    • VK_BLEND_OP_HARDLIGHT_EXT

    • VK_BLEND_OP_SOFTLIGHT_EXT

    • VK_BLEND_OP_DIFFERENCE_EXT

    • VK_BLEND_OP_EXCLUSION_EXT

    • VK_BLEND_OP_INVERT_EXT

    • VK_BLEND_OP_INVERT_RGB_EXT

    • VK_BLEND_OP_LINEARDODGE_EXT

    • VK_BLEND_OP_LINEARBURN_EXT

    • VK_BLEND_OP_VIVIDLIGHT_EXT

    • VK_BLEND_OP_LINEARLIGHT_EXT

    • VK_BLEND_OP_PINLIGHT_EXT

    • VK_BLEND_OP_HARDMIX_EXT

    • VK_BLEND_OP_HSL_HUE_EXT

    • VK_BLEND_OP_HSL_SATURATION_EXT

    • VK_BLEND_OP_HSL_COLOR_EXT

    • VK_BLEND_OP_HSL_LUMINOSITY_EXT

    • VK_BLEND_OP_PLUS_EXT

    • VK_BLEND_OP_PLUS_CLAMPED_EXT

    • VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT

    • VK_BLEND_OP_PLUS_DARKER_EXT

    • VK_BLEND_OP_MINUS_EXT

    • VK_BLEND_OP_MINUS_CLAMPED_EXT

    • VK_BLEND_OP_CONTRAST_EXT

    • VK_BLEND_OP_INVERT_OVG_EXT

    • VK_BLEND_OP_RED_EXT

    • VK_BLEND_OP_GREEN_EXT

    • VK_BLEND_OP_BLUE_EXT

New Enums

New Functions

None.

Issues

None.

Version History

  • Revisions 1-2, 2017-06-12 (Jeff Bolz)

    • Internal revisions

VK_EXT_conditional_rendering

Name String

VK_EXT_conditional_rendering

Extension Type

Device extension

Registered Extension Number

82

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Vikram Kushwaha @vkushwaha

Last Modified Date

2018-05-21

IP Status

No known IP claims.

Contributors
  • Vikram Kushwaha, NVIDIA

  • Daniel Rakos, AMD

  • Jesse Hall, Google

  • Jeff Bolz, NVIDIA

  • Piers Daniell, NVIDIA

  • Stuart Smith, Imagination Technologies

This extension allows the execution of one or more rendering commands to= be conditional on a value in buffer memory. This may help an application reduce the latency by conditionally discarding rendering commands without application intervention. The conditional rendering commands are limited to draws, compute dispatches and clearing attachments within a conditional rendering block.

New Object Types

None.

New Enum Constants

Issues

1) Should conditional rendering affect copy and blit commands?

RESOLVED: Conditional rendering should not affect copies and blits.

2) Should secondary command buffers be allowed to execute while conditio= nal rendering is active in the primary command buffer?

RESOLVED: The rendering commands in secondary command buffer will be affected by an active conditional rendering in primary command buffer if th= e conditionalRenderingEnable is set to VK_TRUE. Conditional rendering must not be active = in the primary command buffer if conditionalRenderingEnable is VK_FALSE.

Examples

None.

Version History

  • Revision 1, 2018-04-19 (Vikram Kushwaha)

    • First Version

  • Revision 2, 2018-05-21 (Vikram Kushwaha)

    • Add new pipeline stage, access flags and limit conditional rendering to a subpass or entire renderpass.

VK_EXT_conservative_rasterizat= ion

Name String

VK_EXT_conservative_rasterization

Extension Type

Device extension

Registered Extension Number

102

Revision

1

Extension and Version Dependencies
Contact
  • Piers Daniell @pdaniell-nv

Last Modified Data

2017-08-28

Contributors
  • Daniel Koch, NVIDIA

  • Daniel Rakos, AMD

  • Jeff Bolz, NVIDIA

  • Slawomir Grajewski, Intel

  • Stu Smith, Imagination Technologies

This extension adds a new rasterization mode called conservative rasterization. There are two modes of conservative rasterization; overestimation and underestimation.

When overestimation is enabled, if any part of the primitive, including = its edges, covers any part of the rectangular pixel area, including its sides, then a fragment is generated with all coverage samples turned on. This extension allows for some variation in implementations by accounting for differences in overestimation, where the generating primitive size is increased at each of its edges by some sub-pixel amount to further increase conservative pixel coverage. Implementations can allow the application to specify an extra overestimatio= n beyond the base overestimation the implementation already does. It also allows implementations to either cull degenerate primitives or rasterize them.

When underestimation is enabled, fragments are only generated if the rectangular pixel area is fully covered by the generating primitive. If supported by the implementation, when a pixel rectangle is fully covered the fragment shader input variable builtin called FullyCoveredEXT is set to true. The shader variable works in either overestimation or underestimation mode.=

Implementations can process degenerate triangles and lines by either discarding them or generating conservative fragments for them. Degenerate triangles are those that end up with zero area after the rasterizer quantizes them to the fixed-point pixel grid. Degenerate lines are those with zero length after quantization.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPE= RTIES_EXT

    • VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE= _INFO_EXT

New Functions

None.

Issues

None.

Version History

  • Revision 1, 2017-08-28 (Piers Daniell)

    • Internal revisions

VK_EXT_debug_utils

Name String

VK_EXT_debug_utils

Extension Type

Instance extension

Registered Extension Number

129

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Mark Young @marky-lunarg

Last Modified Date

2017-09-14

Revision

1

IP Status

No known IP claims.

Dependencies
  • This extension is written against version 1.0 of the Vulkan API.

  • Requires VkObjectType

Contributors
  • Mark Young, LunarG

  • Baldur Karlsson

  • Ian Elliott, Google

  • Courtney Goeltzenleuchter, Google

  • Karl Schultz, LunarG

  • Mark Lobodzinski, LunarG

  • Mike Schuchardt, LunarG

  • Jaakko Konttinen, AMD

  • Dan Ginsburg, Valve Software

  • Rolando Olivares, Epic Games

  • Dan Baker, Oxide Games

  • Kyle Spagnoli, NVIDIA

  • Jon Ashburn, LunarG

Due to the nature of the Vulkan interface, there is very little error information available to the developer and application. By using the VK_EXT_debug_utils extension, developers can obtain more information. When combined with validation layers, even more detailed feedback on the application=E2=80=99s use of Vulkan will be provided.

This extension provides the following capabilities:

  • The ability to create a debug messenger which will pass along debug messages to an application supplied callback.

  • The ability to identify specific Vulkan objects using a name or tag to improve tracking.

  • The ability to identify specific sections within a VkQueue = or VkCommandBuffer using labels to aid organization and offline analysis in external tools.

The main difference between this extension and VK_EXT_debug_marker is that those ext= ensions use VkDebugReportObjectTypeEXT to identify obje= cts. This extension uses the core VkObjectType in place of VkDebugReportObjectTypeEXT. The primary reason for this move is that no future object type handle enumeration values will be added to VkDebugReportObjectTypeEXT= since the creation of VkObjectType.

In addition, this extension combines the functionality of both VK_EXT_debug_report and VK_EXT_debug_marker by allowing object name and debug markers (now called labels) to be returned to the application=E2=80=99s callback function. This should assist in clarifying the details of a debug message including: what objects are involved and potentially which location within a VkQueue o= r VkCommandBuffer the message occurred.

New Object Types

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT

    • VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT

    • VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT

    • VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT

    • VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT

  • Extending VkResult:

    • VK_ERROR_VALIDATION_FAILED_EXT

Examples

Example 1

VK_EXT_debug_utils allows an application to register multip= le callbacks with any Vulkan component wishing to report debug information. Some callbacks may log the information to a file, others may cause a debug break point or other application defined behavior. An application can register callbacks eve= n when no validation layers are enabled, but they will only be called for loader and, if implemented, drive= r events.

To capture events that occur while creating or destroying an instance an application can link a VkDebugUtilsMessengerCreateInfoEXT structure to the pNext element of the VkInstanceCr= eateInfo structure given to vkCreateInstance. This callback is only valid for the duration of the vkCre= ateInstance and the vkDestroyInstance call. Use vkCreateDebugUtilsMessengerEXT to c= reate persistent callback objects.

Example uses: Create three callback objects. One will log errors and warnings to the debug console using Windows OutputDebugString. The second will cause the debugger to break at that callback when an error happens and the third will log warnings to stdout.

    extern VkInstance instance;
    VkResult res;
    VkDebugUtilsMessengerEXT cb1, cb2, cb3;

    // Must call extension functions through a func=
tion pointer:
    PFN_vkCreateDebugUtilsMessengerEXT pfnCreateDebugUtilsMessengerEXT =3D =
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetDeviceProcAddr(device, "vkCre=
ateDebugUtilsMessengerEXT");
    PFN_vkDestroyDebugUtilsMessengerEXT pfnDestroyDebugUtilsMessengerEXT =
=3D (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetDeviceProcAddr(device, "=
vkDestroyDebugUtilsMessengerEXT");

    VkDebugUtilsMessengeCreateInfoEXT callback1 =3D {
            VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,  // sType
            NULL,               =
                                      // pNext
            0,                              =
                          // flags
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |           // messageSeverity
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |             // messageType
            VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
            myOutputDebugString,                                      // pfnUserCallback
            NULL                =
                                      // pUserData<=
/span>
    };
    res =3D pfnCreateDebugUtilsMessengerEXT(instance, &callback1, &=
cb1);
    if (res !=3D VK_SUCCESS) {
       // Do error handling for VK_ERROR_OUT_OF_MEM=
ORY
    }

    callback1.messageSeverity =3D VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT=
_EXT;
    callback1.pfnCallback =3D myDebugBreak;
    callback1.pUserData =3D NULL=
;
    res =3D pfnCreateDebugUtilsMessengerEXT(instance, &callback1, &=
cb2);
    if (res !=3D VK_SUCCESS) {
       // Do error handling for VK_ERROR_OUT_OF_MEM=
ORY
    }

    VkDebugUtilsMessengerCreateInfoEXT callback3 =3D {
            VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,  // sType
            NULL,               =
                                      // pNext
            0,                              =
                          // flags
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,          // messageSeverity
            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |             // messageType
            VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
            mystdOutLogger,                                           // pfnUserCallback
            NULL                =
                                      // pUserData<=
/span>
    };
    res =3D pfnCreateDebugUtilsMessengerEXT(instance, &callback3, &=
cb3);
    if (res !=3D VK_SUCCESS) {
       // Do error handling for VK_ERROR_OUT_OF_MEM=
ORY
    }

    ...

    // Remove callbacks when cleaning up
    pfnDestroyDebugUtilsMessengerEXT(instance, cb1);
    pfnDestroyDebugUtilsMessengerEXT(instance, cb2);
    pfnDestroyDebugUtilsMessengerEXT(instance, cb3);

Example 2

Associate a name with an image, for easier debugging in external tools o= r with validation layers that can print a friendly name when referring to objects in error messages.

    extern VkDevice device;
    extern VkImage image;

    // Must call extension functions through a func=
tion pointer:
    PFN_vkSetDebugUtilsObjectNameEXT pfnSetDebugUtilsObjectNameEXT =3D (PFN=
_vkSetDebugUtilsObjectNameEXT)vkGetDeviceProcAddr(device, "vkSetDebugU=
tilsObjectNameEXT");

    // Set a name on the image
    const VkDebugUtilsObjectNameInfoEXT im=
ageNameInfo =3D
    {
        VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, // sType
        NULL,                   =
                            // pNext
        VK_OBJECT_TYPE_IMAGE,                               // objectType
        (uint64_t)image,                                    // object
        "Brick Diffuse Texture",                            // pObjectName=

    };

    pfnSetDebugUtilsObjectNameEXT(device, &imageNameInfo);

    // A subsequent error might print:
    //   Image 'Brick Diffuse Texture' (0xc0dec0ded=
eadbeef) is used in a
    //   command buffer with no memory bound to it.=

Example 3

Annotating regions of a workload with naming information so that offline analysis tools can display a more usable visualization of the commands submitted.

    extern VkDevice device;
    extern VkCommandBuffer commandBuffer;

    // Must call extension functions through a func=
tion pointer:
    PFN_vkQueueBeginDebugUtilsLabelEXT pfnQueueBeginDebugUtilsLabelEXT =3D =
(PFN_vkQueueBeginDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkQue=
ueBeginDebugUtilsLabelEXT");
    PFN_vkQueueEndDebugUtilsLabelEXT pfnQueueEndDebugUtilsLabelEXT =3D (PFN=
_vkQueueEndDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkQueueEndD=
ebugUtilsLabelEXT");
    PFN_vkCmdBeginDebugUtilsLabelEXT pfnCmdBeginDebugUtilsLabelEXT =3D (PFN=
_vkCmdBeginDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdBeginD=
ebugUtilsLabelEXT");
    PFN_vkCmdEndDebugUtilsLabelEXT pfnCmdEndDebugUtilsLabelEXT =3D (PFN_vkC=
mdEndDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, =
"vkCmdEndDebugUtil=
sLabelEXT");
    PFN_vkCmdInsertDebugUtilsLabelEXT pfnCmdInsertDebugUtilsLabelEXT =3D (P=
FN_vkCmdInsertDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdIns=
ertDebugUtilsLabelEXT");

    // Describe the area being rendered
    const VkDebugUtilsLabelEXT houseLabel =
=3D
    {
        VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, //=
 sType
        NULL,                   =
                 // pNext
        "Brick House", =
                          // pLabelName
        { 1.0f, <=
span class=3D"float">0.0f, 0.0f, =
1.0f },              // color
    };

    // Start an annotated group of calls under the =
'Brick House' name
    pfnCmdBeginDebugUtilsLabelEXT(commandBuffer, &houseLabel);
    {
        // A mutable structure for each part being =
rendered
        VkDebugUtilsLabelEXT housePartLabel =3D
        {
            VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, // sType
            NULL,               =
                     // pNext
            NULL,               =
                     // pLabelName
            { 0.0f, 0.0f, 0.0f, 0.0f },              // color
        };

        // Set the name and insert the marker
        housePartLabel.pLabelName =3D "Walls";
        pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel);

        // Insert the drawcall for the walls
        vkCmdDrawIndexed(commandBuffer, 1000=
, 1, 0, 0, 0);

        // Insert a recursive region for two sets o=
f windows
        housePartLabel.pLabelName =3D "Windows";
        pfnCmdBeginDebugUtilsLabelEXT(commandBuffer, &housePartLabel);
        {
            vkCmdDrawIndexed(commandBuffer, 75, 6, 1000, =
0, 0);
            vkCmdDrawIndexed(commandBuffer, 100, 2, 1450,=
 0, 0);
        }
        pfnCmdEndDebugUtilsLabelEXT(commandBuffer);

        housePartLabel.pLabelName =3D "Front Door";
        pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel);

        vkCmdDrawIndexed(commandBuffer, 350,=
 1, 1650, 0, 0);

        housePartLabel.pLabelName =3D "Roof";
        pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel);

        vkCmdDrawIndexed(commandBuffer, 500,=
 1, 2000, 0, 0);
    }
    // End the house annotation started above
    pfnCmdEndDebugUtilsLabelEXT(commandBuffer);

    // Do other work

    vkEndCommandBuffer(commandBuffer);

    // Describe the queue being used
    const VkDebugUtilsLabelEXT queueLabel =
=3D
    {
        VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, //=
 sType
        NULL,                   =
                 // pNext
        "Main Render Work",                      // pLabelName
        { 0.0f, <=
span class=3D"float">1.0f, 0.0f, =
1.0f },              // color
    };

    // Identify the queue label region
    pfnQueueBeginDebugUtilsLabelEXT(queue, &queueLabel);

    // Submit the work for the main render thread
    const VkCommandBuffer cmd_bufs[] =3D {=
commandBuffer};
    VkSubmitInfo submit_info =3D {.sType =3D VK_STRUCTURE_TYPE_SUBMIT_INFO,
                                .pNext =3D NULL,
                                .waitSemaphoreCount =3D 0,
                                .pWaitSemaphores =3D NULL,
                                .pWaitDstStageMask =3D NULL,
                                .commandBufferCount =3D 1,
                                .pCommandBuffers =3D cmd_bufs,
                                .signalSemaphoreCount =3D 0,
                                .pSignalSemaphores =3D NULL};
    vkQueueSubmit(queue, 1, &submit_info=
, fence);

    // End the queue label region
    pfnQueueEndDebugUtilsLabelEXT(queue);

Issues

1) Should we just name this extension VK_EXT_debug_report2<= /p>

RESOLVED: No. There is enough additional changes to the structures to break backwards compatibility. So, a new name was decided that would not indicate any interaction with the previous extension.

2) Will validation layers immediately support all the new features.

RESOLVED: Not immediately. As one can imagine, there is a lot of work involved with converting the validation layer logging over to the new functionality. Basic logging, as seen in the origin VK_EXT_debug_report extension will be made availab= le immediately. However, adding the labels and object names will take time. Since the priority for Khronos at this time is to continue focusing on Vali= d Usage statements, it may take a while before the new functionality is fully exposed.

3) If the validation layers won=E2=80=99t expose the new functionality i= mmediately, then what=E2=80=99s the point of this extension?

RESOLVED: We needed a replacement for VK_EXT_debug_report because the VkDebugReportObjectTypeEXT enumeration will= no longer be updated and any new objects will need to be debugged using the new functionality provided by this extension.

4) Should this extension be split into two separate parts (1 extension t= hat is an instance extension providing the callback functionality, and another device extension providing the general debug marker and annotation functionality)?

RESOLVED: No, the functionality for this extension is t= oo closely related. If we did split up the extension, where would the structures and enums live= , and how would you define that the device behavior in the instance extension is really only valid if the device extension is enabled, and the functionality is passed in. It=E2=80=99s cleaner to just define this all as an instance extension, plus= it allows the application to enable all debug functionality provided with one enable string during vkCreateInstance.

Version History

  • Revision 1, 2017-09-14 (Mark Young and all listed Contributors)

VK_EXT_depth_range_unrestricted<= /h4>
Name String

VK_EXT_depth_range_unrestricted

Extension Type

Device extension

Registered Extension Number

14

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Piers Daniell @pdaniell-nv

Last Modified Date

2017-06-22

Contributors
  • Daniel Koch, NVIDIA

  • Jeff Bolz, NVIDIA

This extension removes the VkViewport minDepth and maxDepth restrictions that the values must be between 0.= 0 and 1.0, inclusive. It also removes the same restriction on VkPipelineDepthStencilStateCreateInf= o minDepthBounds and maxDepthBounds. Finally it removes the restriction on the depth value in VkClearDepthStencilValue.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

Issues

1) How do VkViewport minDepth and max= Depth values outside of the 0.0 to 1.0 range interact with Primitive Clipping?

RESOLVED: The behavior described in Primitive Clipping still applies. If depth clamping is disabled the depth values are still clipped to 0 =E2=89=A4 zc =E2=89=A4 wc before the viewport = transform. If depth clamping is enabled the above equation is ignored and the depth values are instead clamped to the VkViewport minDepth= and maxDepth values, which in the case of this extension can be ou= tside of the 0.0 to 1.0 range.

2) What happens if a resulting depth fragment is outside of the 0.= 0 to 1.0 range and the depth buffer is fixed-point rather than floa= ting-point?

RESOLVED: The supported range of a fixed-point depth bu= ffer is 0.0 to 1.0 and depth fragments are clamped to this range.

Version History

  • Revision 1, 2017-06-22 (Piers Daniell)

    • Internal revisions

VK_EXT_descriptor_indexing

Name String

VK_EXT_descriptor_indexing

Extension Type

Device extension

Registered Extension Number

162

Revision

2

Extension and Version Dependencies
Contact
  • Jeff Bolz @jeffbolznv

Status

Complete

Last Modified Data

2017-10-02

Contributors
  • Jeff Bolz, NVIDIA

  • Daniel Rakos, AMD

  • Slawomir Grajewski, Intel

  • Tobias Hector, Imagination Technologies

This extension adds several small features which together enable applications to create large descriptor sets containing substantially all o= f their resources, and selecting amongst those resources with dynamic (non-uniform) indexes in the shader. There are feature enables and SPIR-V capabilities for non-uniform descripto= r indexing in the shader, and non-uniform indexing in the shader requires use of a new NonUniformEXT decoration defined in the SPV_EXT_descriptor_indexing SPIR-V extension. There are descriptor set layout binding creation flags enabling several features:

  • Descriptors can be updated after they are bound to a command buffer, such that the execution of the command buffer reflects the most recent update to the descriptors.

  • Descriptors that are not used by any pending command buffers can be updated, which enables writing new descriptors for frame N+1 while frame N is executing.

  • Relax the requirement that all descriptors in a binding that is "statically used" must be valid, such that descriptors that are not accessed by a submission need not be valid and can be updated while that submission is executing.

  • The final binding in a descriptor set layout can have a variable size (and unsized arrays of resources are allowed in the GL_EXT_nonuniform_qualifier and SPV_EXT_descriptor_indexing extensions).

Note that it is valid for multiple descriptor arrays in a shader to use = the same set and binding number, as long as they are all compatible with the descriptor type in the pipeline layout. This means a single array binding in the descriptor set can serve multiple texture dimensionalities, or an array of buffer descriptors can be used wit= h multiple different block layouts.

There are new descriptor set layout and descriptor pool creation flags t= hat are required to opt in to the update-after-bind functionality, and there ar= e separate maxPerStage* and maxDescriptorSet* limit= s that apply to these descriptor set layouts which may be= much higher than the pre-existing limits. The old limits only count descriptors in non-updateAfterBind descriptor set layouts, and the new limits count descriptors in all descriptor set layouts in the pipeline layout.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_= EXT

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT=

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_E= XT

    • VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCAT= E_INFO_EXT

    • VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_= SUPPORT_EXT

  • Extending VkDescriptorPoolCreateFlagBits= :

    • VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT

  • Extending VkDescriptorSetLayoutCrea= teFlagBits:

    • VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT

  • Extending VkResult:

    • VK_ERROR_FRAGMENTATION_EXT

New Functions

None.

Issues

None.

Version History

  • Revision 1, 2017-07-26 (Jeff Bolz)

    • Internal revisions

VK_EXT_direct_mode_display

Name String

VK_EXT_direct_mode_display

Extension Type

Instance extension

Registered Extension Number

89

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2016-12-13

IP Status

No known IP claims.

Contributors
  • Pierre Boudier, NVIDIA

  • James Jones, NVIDIA

  • Damien Leone, NVIDIA

  • Pierre-Loup Griffais, Valve

  • Liam Middlebrook, NVIDIA

This is extension, along with related platform exentions, allows applications to take exclusive control of displays associated with a native windowing system. This is especially useful for virtual reality applications that wish to hid= e HMDs (head mounted displays) from the native platform=E2=80=99s display man= agement system, desktop, and/or other applications.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

Issues

1) Should this extension and its related platform-specific extensions leverage VK_KHR_display, or provide separa= te equivalent interfaces.

RESOLVED: Use VK_KHR_display<= /code> concepts and objects. VK_KHR_display can be used to enumerate al= l displays on the system, including those attached to/in use by a window system or native platform, but VK_KHR_display_swapchain wil= l fail to create a swapchain on in-use displays. This extension and its platform-specific children will allow applications t= o grab in-use displays away from window systems and/or native platforms, allowing them to be used with VK_KHR_displa= y_swapchain.

2) Are separate calls needed to acquire displays and enable direct mode?=

RESOLVED: No, these operations happen in one combined c= ommand. Acquiring a display puts it into direct mode.

Version History

  • Revision 1, 2016-12-13 (James Jones)

    • Initial draft

VK_EXT_discard_rectangles

Name String

VK_EXT_discard_rectangles

Extension Type

Device extension

Registered Extension Number

100

Revision

1

Extension and Version Dependencies
Contact
  • Piers Daniell @pdaniell-nv

Last Modified Date

2016-12-22

Interactions and External Dependencies
  • Interacts with VK_KHR_device_group

  • Interacts with Vulkan 1.1

Contributors
  • Daniel Koch, NVIDIA

  • Jeff Bolz, NVIDIA

This extension provides additional orthogonally aligned =E2=80=9Cdiscard rectangles=E2=80=9D specified in framebuffer-space coordinates that restric= t rasterization of all points, lines and triangles.

From zero to an implementation-dependent limit (specified by maxDiscardRectangles) number of discard rectangles can be oper= ational at once. When one or more discard rectangles are active, rasterized fragments can either survive if the fragment is within any of the operational discard rectangles (VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT mode) or b= e rejected if the fragment is within any of the operational discard rectangle= s (VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT mode).

These discard rectangles operate orthogonally to the existing scissor te= st functionality. The discard rectangles can be different for each physical device in a devic= e group by specifying the device mask and setting discard rectangle dynamic state.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT=

    • VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT=

  • Extending VkDynamicState

    • VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT

Issues

None.

Version History

  • Revision 1, 2016-12-22 (Piers Daniell)

    • Internal revisions

VK_EXT_display_control

Name String

VK_EXT_display_control

Extension Type

Device extension

Registered Extension Number

92

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2016-12-13

IP Status

No known IP claims.

Contributors
  • Pierre Boudier, NVIDIA

  • James Jones, NVIDIA

  • Damien Leone, NVIDIA

  • Pierre-Loup Griffais, Valve

  • Daniel Vetter, Intel

This extension defines a set of utility functions for use with the VK_KHR_display and VK_KHR_display_swapchain extensions.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT

    • VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT

    • VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT

    • VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT

Issues

1) Should this extension add an explicit =E2=80=9CWaitForVsync=E2=80=9D = API or a fence signaled at vsync that the application can wait on?

RESOLVED: A fence. A separate API could later be provided that allows exporting the fence to a native object that could be inserted into standard run loops on POSIX and Windows systems.

2) Should callbacks be added for a vsync event, or in general to monitor events in Vulkan?

RESOLVED: No, fences should be used. Some events are generated by interrupts which are managed in the kernel. In order to use a callback provided by the application, drivers would need to have the userspace driver spawn threads that would wait on the kernel event, and hence the callbacks could be difficult for the application to synchronize with its other work given they would arrive on a foreign thread= .

3) Should vblank or scanline events be exposed?

RESOLVED: Vblank events. Scanline events could be added by a separate extension, but the latency of processing an interrupt and waking up a userspace event is high enough that the accuracy of a scanline event would be rather low. Further, per-scanline interrupts are not supported by all hardware.

Version History

  • Revision 1, 2016-12-13 (James Jones)

    • Initial draft

VK_EXT_display_surface_counter
Name String

VK_EXT_display_surface_counter

Extension Type

Instance extension

Registered Extension Number

91

Revision

1

Extension and Version Dependencies
Contact
  • James Jones @cubanismo

Last Modified Date

2016-12-13

IP Status

No known IP claims.

Contributors
  • Pierre Boudier, NVIDIA

  • James Jones, NVIDIA

  • Damien Leone, NVIDIA

  • Pierre-Loup Griffais, Valve

  • Daniel Vetter, Intel

This is extension defines a vertical blanking period counter associated = with display surfaces. It provides a mechanism to query support for such a counter from a VkSurfaceKHR object.

New Enum Constants

New Structures

Issues

None.

Version History

  • Revision 1, 2016-12-13 (James Jones)

    • Initial draft

VK_EXT_external_memory_dma_buf
Name String

VK_EXT_external_memory_dma_buf

Extension Type

Device extension

Registered Extension Number

126

Revision

1

Extension and Version Dependencies
Contact
  • Chad Versace @chadversary

Last Modified Date

2017-10-10

IP Status

No known IP claims.

Contributors
  • Chad Versace, Google

  • James Jones, NVIDIA

  • Jason Ekstrand, Intel

A dma_buf is a type of file descriptor, defined by the Linux kernel, tha= t allows sharing memory across kernel device drivers and across processes. This extension enables applications to import a dma_buf as VkDeviceMemory; to export VkDeviceMemor= y as a dma_buf; and to create VkBuffer objects that can be bound to that memory.

New Enum Constants

Issues

1. How does the application, when creating a VkImage that it i= ntends to bind to dma_buf VkDeviceMemory that contains an e= xternally produced image, specify the memory layout (such as row pitch and DRM format modifier) of the VkImage? In other words, how does t= he application achieve behavior comparable to that provided by EGL_EXT_image_dma_buf_import and EGL_EXT_image_dma_buf_import_modifiers?

+

2. Without the ability to specify the memory layout of external dma_buf images, how is this extension useful?

+

RESOLVED. This extension provides exactly one new feature: the ability to import/export between dma_bufs and VkDeviceMemory. This feature, together with features provided by VK_KHR_external_memory_fd, is s= ufficient to bind a VkBuffer to dma_buf.

Version History

  • Revision 1, 2017-10-10 (Chad Versace)

    • Squashed internal revisions

VK_EXT_external_memory_host

Name String

VK_EXT_external_memory_host

Extension Type

Device extension

Registered Extension Number

179

Revision

1

Extension and Version Dependencies
Contact
  • Daniel Rakos @drakos-amd

Last Modified Date

2017-11-10

IP Status

No known IP claims.

Contributors
  • Jaakko Konttinen, AMD

  • David Mao, AMD

  • Daniel Rakos, AMD

  • Tobias Hector, Imagination Technologies

  • Jason Ekstrand, Intel

  • James Jones, NVIDIA

This extension enables an application to import host allocations and hos= t mapped foreign device memory to Vulkan memory objects.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT

    • VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_= EXT

  • Extending VkExternalMemoryHandleT= ypeFlagBitsKHR:

    • VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT

    • VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT<= /code>

New Enums

None.

Issues

1) What memory type has to be used to import host pointers?

RESOLVED: Depends on the implementation. Applications have to use the new vkGet= MemoryHostPointerPropertiesEXT command to query the supported memory types for a particular host pointer. The reported memory types may include memory types that come from a memory heap that is otherwise not usable for regular memory object allocation and thus such a heap=E2=80=99s size may be zero.

2) Can the application still access the contents of the host allocation after importing?

RESOLVED: Yes. However, usual synchronization requirements apply.

3) Can the application free the host allocation?

RESOLVED: No, it violates valid usage conditions. Using the memory object imported from a host allocation that=E2=80=99s alre= ady freed thus results in undefined behavior.

4) Is vkMapMemory expected to return the same host addr= ess which was specified when importing it to the memory object?

RESOLVED: No. Implementations are allowed to return the same address but it=E2=80=99s not required. Some implementations might return a different virtual mapping of the allocation, although the same physical pages will be used.

5) Is there any limitation on the alignment of the host pointer and/or s= ize?

RESOLVED: Yes. Both the address and the size have to be an integer multiple of minImportedHostPointerAlignment. In addition, some platforms and foreign devices may have additional restrictions.

6) Can the same host allocation be imported multiple times into a given physical device?

RESOLVED: No, at least not guaranteed by this extension. Some platforms do not allow locking the same physical pages for device access multiple times, so attempting to do it may result in undefined behavior.

7) Does this extension support exporting the new handle type?

RESOLVED: No.

8) Should we include the possibility to import host mapped foreign devic= e memory using this API?

RESOLVED: Yes, through a separate handle type. Implementations are still allowed to support only one of the handle types introduced by this extension by not returning import support for a particular handle type as returned in VkExte= rnalMemoryPropertiesKHR.

Version History

  • Revision 1, 2017-11-10 (Daniel Rakos)

    • Internal revisions

VK_EXT_global_priority

Name String

VK_EXT_global_priority

Extension Type

Device extension

Registered Extension Number

175

Revision

2

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Andres Rodriguez @lostgoat

Last Modified Date

2017-10-06

IP Status

No known IP claims.

Contributors
  • Andres Rodriguez, Valve

  • Pierre-Loup Griffais, Valve

  • Dan Ginsburg, Valve

  • Mitch Singer, AMD

In Vulkan, users can specify device-scope queue priorities. In some cases it may be useful to extend this concept to a system-wide scope. This extension provides a mechanism for caller=E2=80=99s to set their syste= m-wide priority. The default queue priority is VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT.

The driver implementation will attempt to skew hardware resource allocat= ion in favour of the higher-priority task. Therefore, higher-priority work may retain similar latency and throughput characteristics even if the system is congested with lower priority work.

The global priority level of a queue shall take predence over the per-process queue priority (VkDeviceQueueCreateInfo::pQueuePriorities).

Abuse of this feature may result in starving the rest of the system from hardware resources. Therefore, the driver implementation may deny requests to acquire a priorit= y above the default priority (VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT) if the caller does not have sufficient privileges. In this scenario VK_ERROR_NOT_PERMITTED_EXT is returned.

The driver implementation may fail the queue allocation request if resou= rces required to complete the operation have been exhausted (either by the same process or a different process). In this scenario VK_ERROR_INITIALIZATION_FAILED is returned.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT

  • Extending VkResult:

    • VK_ERROR_NOT_PERMITTED_EXT

New Functions

None.

Issues

None.

Version History

  • Revision 2, 2017-11-03 (Andres Rodriguez)

    • Fixed VkQueueGlobalPriorityEXT missing _EXT suffix

  • Revision 1, 2017-10-06 (Andres Rodriguez)

    • First version.

VK_EXT_hdr_metadata

Name String

VK_EXT_hdr_metadata

Extension Type

Device extension

Registered Extension Number

106

Revision

1

Extension and Version Dependencies
Contact
  • Courtney Goeltzenleuchter @courtney-g

Last Modified Date

2017-03-04

IP Status

No known IP claims.

Contributors
  • Courtney Goeltzenleuchter, Google

This extension defines two new structures and a function to assign SMPTE (the Society of Motion Picture and Television Engineers) 2086 metadata and CTA (Consumer Technology Assocation) 861.3 metadata to a swapchain. The metadata includes the color primaries, white point, and luminance range of the mastering display, which all together define the color volume that contains all the possible colors the mastering display can produce. The mastering display is the display where creative work is done and creative intent is established. To preserve such creative intent as much as possible and achieve consistent color reproduction on different viewing displays, it is useful for the display pipeline to know the color volume of the original mastering display where content was created or tuned. This avoids performing unnecessary mapping of colors that are not displayable on the original mastering display. The metadata also includes the maxContentLightLevel and maxFrameAverageLightLevel as defined by CTA 861.3.

While the general purpose of the metadata is to assist in the transforma= tion between different color volumes of different displays and help achieve better color reproduction, it is not in the scope of this extension to define how exactly the metadata should be used in such a process. It is up to the implementation to determine how to make use of the metadata= .

New Enum Constants

New Functions

Issues

1) Do we need a query function?

PROPOSED: No, Vulkan does not provide queries for state= that the application can track on its own.

2) Should we specify default if not specified by the application?

PROPOSED: No, that leaves the default up to the display= .

Version History

  • Revision 1, 2016-12-27 (Courtney Goeltzenleuchter)

    • Initial version

VK_EXT_post_depth_coverage

Name String

VK_EXT_post_depth_coverage

Extension Type

Device extension

Registered Extension Number

156

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Koch @dgkoch

Last Modified Date

2017-07-17

Interactions and External Dependencies
Contributors
  • Jeff Bolz, NVIDIA

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_KHR_post_depth_coverage

which allows the fragment shader to control whether values in the SampleMask built-in input variable reflect the coverage after = the early per-fragment depth and stencil tests are applied.<= /p>

This extension adds a new PostDepthCoverage execution mode = under the SampleMaskPostDepthCoverage capability. When this mode is specified along with EarlyFragmentTests, the= value of an input variable decorated with the SampleMask built-= in reflects the coverage after the early fragment tests are applied. Otherwise, it reflects the coverage before the depth and stencil tests.

When using GLSL source-based shading languages, the post_depth_cov= erage layout qualifier from GL_ARB_post_depth_coverage or GL_EXT_post_depth_coverage maps to the PostDepthCoverage execu= tion mode.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

New Built-In Variables

None.

New Variable Decoration

None.

New SPIR-V Capabilities

Issues

None yet.

Version History

  • Revision 1, 2017-07-17 (Daniel Koch)

    • Internal revisions

VK_EXT_queue_family_foreign

Name String

VK_EXT_queue_family_foreign

Extension Type

Device extension

Registered Extension Number

127

Revision

1

Extension and Version Dependencies
Contact
  • Chad Versace @chadversary

Last Modified Date

2017-11-01

IP Status

No known IP claims.

Contributors
  • Chad Versace, Google

  • James Jones, NVIDIA

  • Jason Ekstrand, Intel

  • Jesse Hall, Google

  • Daniel Rakos, AMD

  • Ray Smith, ARM

This extension defines a special queue family, VK_QUEUE_FAMILY_FOREIGN_EXT, which can be used to transfer own= ership of resources backed by external memory to foreign, external queues. This is similar to VK_QUEUE_FAMILY_EXTERNAL_KHR, defined in VK_KHR_external_memory. The key differences between the two are:

  • The queues represented by VK_QUEUE_FAMILY_EXTERNAL_KHR must= share the same physical device and the same driver version as the current VkInstance. VK_QUEUE_FAMILY_FOREIGN_EXT has no such restrictions. It can represent devices and drivers from other vendors, and can even represent non-Vulkan-capable devices.

  • All resources backed by external memory support VK_QUEUE_FAMILY_EXTERNAL_KHR. Support for VK_QUEUE_FAMILY_FOREIGN_EXT is more restrictive.

  • Applications should expect transitions to/from VK_QUEUE_FAMILY_FOREIGN_EXT to be more expensive than transiti= ons to/from VK_QUEUE_FAMILY_EXTERNAL_KHR.

New Enum Constants

  • Special constants:

    • VK_QUEUE_FAMILY_FOREIGN_EXT

Version History

  • Revision 1, 2017-11-01 (Chad Versace)

    • Squashed internal revisions

VK_EXT_sample_locations

Name String

VK_EXT_sample_locations

Extension Type

Device extension

Registered Extension Number

144

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Rakos @drakos-amd

Last Modified Date

2017-08-02

Contributors
  • Mais Alnasser, AMD

  • Matthaeus G. Chajdas, AMD

  • Maciej Jesionowski, AMD

  • Daniel Rakos, AMD

  • Slawomir Grajewski, Intel

  • Jeff Bolz, NVIDIA

  • Bill Licea-Kane, Qualcomm

This extension allows an application to modify the locations of samples within a pixel used in rasterization. Additionally, it allows applications to specify different sample locations for each pixel in a group of adjacent pixels, which can increase antialiasing quality (particularly if a custom resolve shader is used that takes advantage of these different locations).

It is common for implementations to optimize the storage of depth values= by storing values that can be used to recons= truct depth at each sample location, rather than storing separate depth values for each sample. For example, the depth values from a single triangle may be represented using plane equations. When the depth value for a sample is needed, it is automatically evaluated at the sample location. Modifying the sample locations causes the reconstruction to no longer evaluate the same depth values as when the samples were originally generated, thus the depth aspect of a depth/stencil attachment must be cleared before rendering to it using different sample locations.

Some implementations may need to evalu= ate depth image values while performing image layout transitions. To accommodate this, instances of the VkSampleLoc= ationsInfoEXT structure can be specified for each situa= tion where an explicit or automatic layout transition has to take place. VkSampleLocationsInfoEXT can be chained from VkImageMemoryBarrier structures to provide sample= locations for layout transitions performed by vkCmdWaitEvents and vkCmdPipelineBarrier calls, and VkRenderPassSampleLocationsBeginIn= foEXT can be chained from VkRenderPassBeginInfo to provide sample location= s for layout transitions performed implicitly by a render pass instance.

New Object Types

None.

New Enum Constants

  • Extending VkImageCreateFlagBits:

    • VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT

    • VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT

    • VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT<= /code>

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT<= /code>

    • VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT

  • Extending VkDynamicState:

    • VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT

New Enums

None.

Issues

None.

Version History

  • Revision 1, 2017-08-02 (Daniel Rakos)

    • Internal revisions

VK_EXT_sampler_filter_minmax

Name String

VK_EXT_sampler_filter_minmax

Extension Type

Device extension

Registered Extension Number

131

Revision

1

Extension and Version Dependencies
Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-05-19

IP Status

No known IP claims.

Contributors
  • Jeff Bolz, NVIDIA

  • Piers Daniell, NVIDIA

In unextended Vulkan, minification and magnification filters such as LIN= EAR allow sampled image lookups to return a filtered texel value produced by computing a weighted average of a collection of texels in the neighborhood of the texture coordinate provided.

This extension provides a new sampler parameter which allows application= s to produce a filtered texel value by computing a component-wise minimum (MIN) or maximum (MAX) of the texels that would normally be averaged. The reduction mode is orthogonal to the minification and magnification filter parameters. The filter parameters are used to identify the set of texels used to produc= e a final filtered value; the reduction mode identifies how these texels are combined.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES= _EXT

    • VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT

  • Extending VkFormatFeatureFlagBits

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT

New Functions

None.

New Built-In Variables

None.

New SPIR-V Capabilities

None.

Issues

None.

Examples

None.

Version History

  • Revision 2, 2017-05-19 (Piers Daniell)

    • Renamed to EXT

  • Revision 1, 2017-03-25 (Jeff Bolz)

    • Internal revisions

VK_EXT_shader_stencil_export

Name String

VK_EXT_shader_stencil_export

Extension Type

Device extension

Registered Extension Number

141

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Dominik Witczak @dominikwitczakamd

Last Modified Date

2017-07-19

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Dominik Witczak, AMD

  • Daniel Rakos, AMD

  • Rex Xu, AMD

This extension adds support for the SPIR-V extension SPV_EXT_shader_stencil_export, providing a mechanism whereby a shader may generate the stencil reference value per invocation. When stencil testing is enabled, this allows the test to be performed against the value generated in the shader.

Version History

  • Revision 1, 2017-07-19 (Dominik Witczak)

    • Initial draft

VK_EXT_shader_subgroup_ballot

Name String

VK_EXT_shader_subgroup_ballot

Extension Type

Device extension

Registered Extension Number

65

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Koch @dgkoch

Last Modified Date

2016-11-28

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Jeff Bolz, NVIDIA

  • Neil Henning, Codeplay

  • Daniel Koch, NVIDIA Corporation

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_KHR_shader_ballot

This extension provides the ability for a group of invocations, which execute in parallel, to do limited forms of cross-invocation communication via a group broadcast of a invocation value, or broadcast of a bitarray representing a predicate value from each invocation in the group.

This extension provides access to a number of additional built-in shader variables in Vulkan:

  • SubgroupEqMaskKHR, which contains the subgroup mask of the = current subgroup invocation,

  • SubgroupGeMaskKHR, which contains the subgroup mask of the invocations greater than or equal to the current invocation,

  • SubgroupGtMaskKHR, which contains the subgroup mask of the invocations greater than the current invocation,

  • SubgroupLeMaskKHR, which contains the subgroup mask of the invocations less than or equal to the current invocation,

  • SubgroupLtMaskKHR, which contains the subgroup mask of the invocations less than the current invocation,

  • SubgroupLocalInvocationId, which contains the index of an invocation within a subgroup, and

  • SubgroupSize, which contains the maximum number of invocati= ons in a subgroup.

Additionally, this extension provides access to the new SPIR-V instructi= ons:

  • OpSubgroupBallotKHR,

  • OpSubgroupFirstInvocationKHR, and

  • OpSubgroupReadInvocationKHR,

When using GLSL source-based shader languages, the following variables a= nd shader functions from GL_ARB_shader_ballot can map to these SPIR-V built-in decorations and instructions:

  • in uint64_t gl_SubGroupEqMaskARB; =E2=86=92 SubgroupE= qMaskKHR,

  • in uint64_t gl_SubGroupGeMaskARB; =E2=86=92 SubgroupG= eMaskKHR,

  • in uint64_t gl_SubGroupGtMaskARB; =E2=86=92 SubgroupG= tMaskKHR,

  • in uint64_t gl_SubGroupLeMaskARB; =E2=86=92 SubgroupL= eMaskKHR,

  • in uint64_t gl_SubGroupLtMaskARB; =E2=86=92 SubgroupL= tMaskKHR,

  • in uint gl_SubGroupInvocationARB; =E2=86=92 SubgroupL= ocalInvocationId,

  • uniform uint gl_SubGroupSizeARB; =E2=86=92 SubgroupSi= ze,

  • ballotARB() =E2=86=92 OpSubgroupBallotKHR,

  • readFirstInvocationARB() =E2=86=92 OpSubgroupFirstInv= ocationKHR, and

  • readInvocationARB() =E2=86=92 OpSubgroupReadInvocatio= nKHR.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

New SPIR-V Capabilities

Issues

None.

Version History

  • Revision 1, 2016-11-28 (Daniel Koch)

    • Initial draft

VK_EXT_shader_subgroup_vote

Name String

VK_EXT_shader_subgroup_vote

Extension Type

Device extension

Registered Extension Number

66

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Koch @dgkoch

Last Modified Date

2016-11-28

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Neil Henning, Codeplay

  • Daniel Koch, NVIDIA Corporation

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_KHR_subgroup_vote

This extension provides new SPIR-V instructions:

  • OpSubgroupAllKHR,

  • OpSubgroupAnyKHR, and

  • OpSubgroupAllEqualKHR.

to compute the composite of a set of boolean conditions across a group o= f shader invocations that are running concurrently (a subgroup). These composite results may be used to execute shaders more efficiently on = a VkPhysicalDevice.

When using GLSL source-based shader languages, the following shader functions from GL_ARB_shader_group_vote can map to these SPIR-V instructions:

  • anyInvocationARB() =E2=86=92 OpSubgroupAnyKHR,=

  • allInvocationsARB() =E2=86=92 OpSubgroupAllKHR= , and

  • allInvocationsEqualARB() =E2=86=92 OpSubgroupAllEqual= KHR.

The subgroup across which the boolean conditions are evaluated is implementation-dependent, and this extension provides no guarantee over how individual shader invocations are assigned to subgroups. In particular, a subgroup has no necessary relationship with the compute shader local workgroup=E2=80=89=E2=80=94=E2=80=89any pair of shade= r invocations in a compute local workgroup may execute in different subgroups as used by these instructions.

Compute shaders operate on an explicitly specified group of threads (a l= ocal workgroup), but many implementations will also group non-compute shader invocations and execute them concurrently. When executing code like

if (condition) {
  result =3D do_fast_path();
} else {
  result =3D do_general_path();
}

where condition diverges between invocations, an implementa= tion might first execute do_fast_path() for the invocations where c= ondition is true and leave the other invocations dormant. Once do_fast_path() returns, it might call do_general_pa= th() for invocations where condition is false and leave th= e other invocations dormant. In this case, the shader executes both the fast and the ge= neral path and might be better off just using the general path for all invocations.

This extension provides the ability to avoid divergent execution by evaluating a condition across an entire subgroup using code like:

if (allInvocationsARB(condition)) {
  result =3D do_fast_path();
} else {
  result =3D do_general_path();
}

The built-in function allInvocationsARB() will return the s= ame value for all invocations in the group, so the group will either execute do_fast_path() or do_general_path(), but never bo= th. For example, shader code might want to evaluate a complex function iteratively by starting with an approximation of the result and then refining the approximation. Some input values may require a small number of iterations to generate an accurate result (do_fast_path) while others require a larger n= umber (do_general_path). In another example, shader code might want to evaluate a complex function (do_general_path) that can be greatly simplified when assuming= a specific value for one of its inputs (do_fast_path).

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

New Built-In Variables

None.

New SPIR-V Capabilities

Issues

None.

Version History

  • Revision 1, 2016-11-28 (Daniel Koch)

    • Initial draft

VK_EXT_shader_viewport_index_= layer

Name String

VK_EXT_shader_viewport_index_layer

Extension Type

Device extension

Registered Extension Number

163

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Koch @dgkoch

Last Modified Date

2017-08-08

Interactions and External Dependencies
Contributors
  • Piers Daniell, NVIDIA

  • Jeff Bolz, NVIDIA

  • Jan-Harald Fredriksen, ARM

  • Daniel Rakos, AMD

  • Slawomir Grajeswki, Intel

This extension adds support for the ShaderViewportIndexLayerEXT capability from the SPV_EXT_shader_viewport_index_layer extension in Vulkan.

This extension allows variables decorated with the Layer an= d ViewportIndex built-ins to be exported from vertex or tessella= tion shaders, using the ShaderViewportIndexLayerEXT capability.

When using GLSL source-based shading languages, the gl_ViewportInd= ex and gl_Layer built-in variables map to the SPIR-V Viewpo= rtIndex and Layer built-in decorations, respectively. Behaviour of these variables is extended as described in the GL_ARB_shader_viewport_layer_array (or the precursor GL_AMD_vertex_shader_layer, GL_AMD_vertex_shader_viewport_index, and GL_NV_viewport_array2 extensions).

Note

The ShaderViewportIndexLayerEXT capability is equivalent to= the ShaderViewportIndexLayerNV capability added by VK_NV_viewport_array2.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

New or Modified Built-In Var= iables

New Variable Decoration

None.

New SPIR-V Capabilities

Issues

None yet!

Version History

  • Revision 1, 2017-08-08 (Daniel Koch)

    • Internal drafts

VK_EXT_swapchain_colorspace

Name String

VK_EXT_swapchain_colorspace

Extension Type

Instance extension

Registered Extension Number

105

Revision

3

Extension and Version Dependencies
Contact
  • Courtney Goeltzenleuchter @courtney-g

Last Modified Date

2017-03-15

IP Status

No known IP claims.

Contributors
  • Courtney Goeltzenleuchter, Google

New Enum Constants

  • Extending VkColorSpaceKHR:

    • VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT - supports the Disp= lay-P3 color space and applies an sRGB-like transfer function.

    • VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT - supports the exte= nded sRGB color space and applies a linear transfer function.

    • VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT - supports the extended sRGB color space with an sRGB nonlinear transfer function.

    • VK_COLOR_SPACE_DCI_P3_LINEAR_EXT - supports the DCI-P3 colo= r space and applies a linear OETF.

    • VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT - supports the DCI-P3 c= olor space and applies the Gamma 2.6 OETF.

    • VK_COLOR_SPACE_BT709_LINEAR_EXT - supports the BT709 color = space and applies a linear transfer function.

    • VK_COLOR_SPACE_BT709_NONLINEAR_EXT - supports the BT709 col= or space and applies the SMPTE 170M OETF.

    • VK_COLOR_SPACE_BT2020_LINEAR_EXT - supports the BT2020 colo= r space and applies a linear OETF.

    • VK_COLOR_SPACE_HDR10_ST2084_EXT - supports HDR10 (BT2020 co= lor space and applies the SMPTE ST2084 Perceptual Quantizer (PQ) OETF).

    • VK_COLOR_SPACE_DOLBYVISION_EXT - supports Dolby Vision (BT2= 020 color space, proprietary encoding, and applies the SMPTE ST2084 OETF).

    • VK_COLOR_SPACE_HDR10_HLG_EXT - supports HDR10 (BT2020 color= space and applies the Hybrid Log Gamma (HLG) OETF).

    • VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT - supports the AdobeRGB = color space and applies a linear OETF.

    • VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT - supports the AdobeR= GB color space and applies the Gamma 2.2 OETF.

    • VK_COLOR_SPACE_PASS_THROUGH_EXT - color components used =E2= =80=9Cas is=E2=80=9D. Intended to allow application to supply data for color spaces not described here.

Issues

1) Does the spec need to specify which kinds of image formats support th= e color spaces?

RESOLVED: Pixel format is independent of color space (t= hough some color spaces really want / need floating point color components to be useful). Therefore, do not plan on documenting what formats support which colorspaces. An application can call vkGetPhysicalDeviceSurfaceFormatsKHR to query what a particular implementation supports.

2) How does application determine if HW supports appropriate transfer function for a colorspace?

RESOLVED: Extension indicates that implementation must not do the OETF encoding if it is not sRGB. That responsibility falls to the application shaders. Any other native OETF / EOTF functions supported by an implementation can b= e described by separate extension.

Version History

  • Revision 1, 2016-12-27 (Courtney Goeltzenleuchter)

    • Initial version

  • Revision 2, 2017-01-19 (Courtney Goeltzenleuchter)

    • Add pass through and multiple options for BT2020.

    • Clean up some issues with equations not displaying properly.

  • Revision 3, 2017-06-23 (Courtney Goeltzenleuchter)

    • Add extended sRGB non-linear enum.

VK_EXT_validation_cache

Name String

VK_EXT_validation_cache

Extension Type

Device extension

Registered Extension Number

161

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Cort Stratton @cdwfs

Last Modified Date

2017-08-29

IP Status

No known IP claims.

Contributors
  • Cort Stratton, Google

  • Chris Forbes, Google

This extension provides a mechanism for caching the results of potential= ly expensive internal validation operations across multiple runs of a Vulkan application. At the core is the VkValidationCacheEXT object ty= pe, which is managed similarly to the existing VkPipelineCache.

The new struct VkShaderModul= eValidationCacheCreateInfoEXT can be included in the pNext chain at vkCreateS= haderModule time. It contains a VkValidationCacheEXT to use when va= lidating the VkShaderModule.

New Object Types

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT

    • VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT

Issues

None.

Version History

  • Revision 1, 2017-08-29 (Cort Stratton)

    • Initial draft

VK_EXT_validation_flags

Name String

VK_EXT_validation_flags

Extension Type

Instance extension

Registered Extension Number

62

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Tobin Ehlis @tobine

Last Modified Date

2016-09-06

IP Status

No known IP claims.

Contributors
  • Tobin Ehlis, Google

  • Courtney Goeltzenleuchter, Google

This extension provides the VkValidationFlagsEXT struct that can be included in the pNext chain of the VkIns= tanceCreateInfo structure passed as the pCreateInfo parameter of vkCreateInstance. The new struct contains an array of VkValidationCheck= EXT values that will be disabled by the validation layers.

New Enum Constants

New Structures

New Functions

None.

Issues

None.

Version History

  • Revision 1, 2016-08-26 (Courtney Goeltzenleuchter)

    • Initial draft

VK_EXT_vertex_attribute_divisor<= /h4>
Name String

VK_EXT_vertex_attribute_divisor

Extension Type

Device extension

Registered Extension Number

191

Revision

2

Extension and Version Dependencies
Contact
  • Vikram Kushwaha @vkushwaha

Last Modified Date

2018-07-16

IP Status

No known IP claims.

Contributors
  • Vikram Kushwaha, NVIDIA

  • Jason Ekstrand, Intel

This extension allows instance-rate vertex attributes to be repeated for certain number of instances instead of advancing for every instance when instanced rendering is enabled.

New Object Types

None.

New Enum Constants

Extending VkStructureType:

  • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERT= IES_EXT

  • VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_= EXT

New Enums

None.

New Functions

None.

Issues

1) What is the effect of a non-zero value for firstInstance= ?

RESOLVED: The Vulkan API should follow the OpenGL conve= ntion and offset attribute fetching by firstInstance while computing vertex att= ribute offsets.

2) Should zero be an allowed divisor?

RESOLVED: No. The zero case in OpenGL is handled in Vulkan by setting the inputRate= on the binding to VK_VERTEX_INPUT_RATE_VERTEX.

Examples

To create a vertex binding such that the first binding uses instanced rendering and the same attribute is used for every 4 draw instances, an application could use the following set of structures:

    const VkVertexInputBindingDivisorDescriptionEXT divisorD=
esc =3D
    {
        0,
        4
    };

    const VkPipelineVertexInputDivisorStat=
eCreateInfoEXT divisorInfo =3D
    {
        VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_E=
XT, // sType
        NULL,                   =
                                          // pNext<=
/span>
        1,                                  =
                              // vertexBindingDivis=
orCount
        &divisorDesc                                                   =
   // pVertexBindingDivisors
    }

    const VkVertexInputBindingDescription =
binding =3D
    {
        0,                                  =
                              // binding
        sizeof(Vertex),                     =
                              // stride
        VK_VERTEX_INPUT_RATE_INSTANCE                                     <=
span class=3D"comment">// inputRate
    };

    const VkPipelineVertexInputStateCreate=
Info viInfo =3D
    {
        VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO,              <=
span class=3D"comment">// sType
        &divisorInfo,                                                  =
   // pNext
        ...
    };
    //...

Version History

  • Revision 1, 2017-12-04 (Vikram Kushwaha)

    • First Version

  • Revision 2, 2018-07-16 (Jason Ekstrand)

    • Adjust the interaction between divisor and firstInsta= nce to match the OpenGL convention.

    • Disallow divisors of zero.

VK_AMD_buffer_marker

Name String

VK_AMD_buffer_marker

Extension Type

Device extension

Registered Extension Number

180

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Rakos @drakos-amd

Last Modified Date

2018-01-26

IP Status

No known IP claims.

Contributors
  • Matthaeus G. Chajdas, AMD

  • Jaakko Konttinen, AMD

  • Daniel Rakos, AMD

This extension adds a new operation to execute pipelined writes of small marker values into a VkBuffer object.

The primary purpose of these markers is to facilitate the development of debugging tools for tracking which pipelined command contributed to device loss.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

Examples

None.

Version History

  • Revision 1, 2018-01-26 (Jaakko Konttinen)

    • Initial revision

VK_AMD_gcn_shader

Name String

VK_AMD_gcn_shader

Extension Type

Device extension

Registered Extension Number

26

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Dominik Witczak @dominikwitczakamd

Last Modified Date

2016-05-30

IP Status

No known IP claims.

Contributors
  • Dominik Witczak, AMD

  • Daniel Rakos, AMD

  • Rex Xu, AMD

  • Graham Sellers, AMD

This extension adds support for the following SPIR-V extension in Vulkan= :

editing-note

Shouldn=E2=80=99t the SPV extension be in the Interactions and External = Dependencies block?

Version History

  • Revision 1, 2016-05-30 (Dominik Witczak)

    • Initial draft

VK_AMD_gpu_shader_half_float

Name String

VK_AMD_gpu_shader_half_float

Extension Type

Device extension

Registered Extension Number

37

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Dominik Witczak @dominikwitczakamd

Last Modified Date

2016-09-21

IP Status

No known IP claims.

Contributors
  • Daniel Rakos, AMD

  • Dominik Witczak, AMD

  • Donglin Wei, AMD

  • Graham Sellers, AMD

  • Qun Lin, AMD

  • Rex Xu, AMD

This extension adds support for the following SPIR-V extension in Vulkan= :

editing-note

Shouldn=E2=80=99t the SPV extension be in the Interactions and External = Dependencies block?

Version History

  • Revision 1, 2019-09-21 (Dominik Witczak)

    • Initial draft

VK_AMD_gpu_shader_int16

Name String

VK_AMD_gpu_shader_int16

Extension Type

Device extension

Registered Extension Number

133

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Qun Lin

  • AMD @linqun

Last Modified Date

2017-06-08

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Daniel Rakos, AMD

  • Dominik Witczak, AMD

  • Matthaeus G. Chajdas, AMD

  • Rex Xu, AMD

  • Timothy Lottes, AMD

  • Zhi Cai, AMD

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_AMD_gpu_shader_int16

Version History

  • Revision 1, 2017-06-18 (Dominik Witczak)

    • First version.

VK_AMD_mixed_attachment_samples<= /h4>
Name String

VK_AMD_mixed_attachment_samples

Extension Type

Device extension

Registered Extension Number

137

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Matthaeus G. Chajdas @anteru

Last Modified Date

2017-07-24

Contributors
  • Mais Alnasser, AMD

  • Matthaeus G. Chajdas, AMD

  • Maciej Jesionowski, AMD

  • Daniel Rakos, AMD

This extension enables applications to use multisampled rendering with a depth/stencil sample count that is larger than the color sample count. Having a depth/stencil sample count larger than the color sample count allows maintaining geometry and coverage information at a higher sample rat= e than color information. All samples are depth/stencil tested, but only the first color sample count number of samples get a corresponding color output.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

Issues

None.

Version History

  • Revision 1, 2017-07-24 (Daniel Rakos)

    • Internal revisions

VK_AMD_rasterization_order

Name String

VK_AMD_rasterization_order

Extension Type

Device extension

Registered Extension Number

19

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Rakos @drakos-amd

Last Modified Date

2016-04-25

IP Status

No known IP claims.

Contributors
  • Matthaeus G. Chajdas, AMD

  • Jaakko Konttinen, AMD

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Dominik Witczak, AMD

This extension introduces the possibility for the application to control= the order of primitive rasterization. In unextended Vulkan, the following stages are guaranteed to execute in API order:

  • depth bounds test

  • stencil test, stencil op, and stencil write

  • depth test and depth write

  • occlusion queries

  • blending, logic op, and color write

This extension enables applications to opt into a relaxed, implementatio= n defined primitive rasterization order that may allow better parallel processing of primitives and thus enabling higher primitive throughput. It is applicable in cases where the primitive rasterization order is known to not affect the output of the rendering or any differences caused by a different rasterization order are not a concern from the point of view of the application=E2=80=99s purpose.

A few examples of cases when using the relaxed primitive rasterization o= rder would not have an effect on the final rendering:

  • If the primitives rendered are known to not overlap in framebuffer space.

  • If depth testing is used with a comparison operator of VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, or VK_COMPARE_OP_GREATER_OR_EQUAL= , and the primitives rendered are known to not overlap in clip space.

  • If depth testing is not used and blending is enabled for all attachments with a commutative blend operator.

New Object Types

None

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER= _AMD

New Functions

None

Issues

1) How is this extension useful to application developers?

RESOLVED: Allows them to increase primitive throughput = for cases when strict API order rasterization is not important due to the nature of the content, the configuration used, or the requirements towards the output of the rendering.

2) How does this extension interact with content optimizations aiming to reduce overdraw by appropriately ordering the input primitives?

RESOLVED: While the relaxed rasterization order might s= omewhat limit the effectiveness of such content optimizations, most of the benefits of it are expected to be retained even when the relaxed rasterization order is used, so applications should still apply these = optimizations even if they intend to use the extension.

3) Are there any guarantees about the primitive rasterization order when using the new relaxed mode?

RESOLVED: No. In this case the rasterization order is completely implementation dependent= , but in practice it is expected to partially still follow the order of incoming primitives.

4) Does the new relaxed rasterization order have any adverse effect on repeatability and other invariance rules of the API?

RESOLVED: Yes, in the sense that it extends the list of= exceptions when the repeatability requirement does not apply.

Examples

None

Issues

None

Version History

  • Revision 1, 2016-04-25 (Daniel Rakos)

    • Initial draft.

VK_AMD_shader_ballot

Name String

VK_AMD_shader_ballot

Extension Type

Device extension

Registered Extension Number

38

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Dominik Witczak @dominikwitczakamd

Last Modified Date

2016-09-19

IP Status

No known IP claims.

Contributors
  • Qun Lin, AMD

  • Graham Sellers, AMD

  • Daniel Rakos, AMD

  • Rex Xu, AMD

  • Dominik Witczak, AMD

  • Matth=C3=A4us G. Chajdas, AMD

This extension adds support for the following SPIR-V extension in Vulkan= :

editing-note

Shouldn=E2=80=99t the SPV extension be in the Interactions and External = Dependencies block?

Version History

  • Revision 1, 2016-09-19 (Dominik Witczak)

    • Initial draft

VK_AMD_shader_core_properties

Name String

VK_AMD_shader_core_properties

Extension Type

Device extension

Registered Extension Number

186

Revision

1

Extension and Version Dependencies
Contact
  • Martin Dinkov @mdinkov

Last Modified Date

2018-02-15

IP Status

No known IP claims.

Contributors
  • Martin Dinkov, AMD

  • Matthaeus Chajdas, AMD

This extension exposes shader core properties for a target physical devi= ce through the VK_KHR_get_physical_device_properties2 extension. Please refer to the example below for proper usage.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD

New Enums

None.

New Functions

None.

Examples

This example retrieves the shader core properties for a physical device.=

extern VkInstance       instance;

PFN_vkGetPhysicalDeviceProperties2 pfnVkGetPhysicalDeviceProperties2 =3D
    reinterpret_cast<PFN_vkGetPhysicalDev=
iceProperties2>
    (vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2") );

VkPhysicalDeviceProperties2             general_props;
VkPhysicalDeviceShaderCorePropertiesAMD shader_core_properties;

shader_core_properties.pNext =3D nullpt=
r;
shader_core_properties.sType =3D VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_C=
ORE_PROPERTIES_AMD;

general_props.pNext =3D &shader_core_properties;
general_props.sType =3D VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;

// After this call, shader_core_properties has been=
 populated
pfnVkGetPhysicalDeviceProperties2(device, &general_props);

printf("Number of shader engines: %d\n",
    m_shader_core_properties.shader_engine_count =3D
    shader_core_properties.shaderEngineCount;
printf("Number of shader arrays: %d\n",
    m_shader_core_properties.shader_arrays_per_engine_count =3D
    shader_core_properties.shaderArraysPerEngineCount;
printf("Number of CUs per shader array: %d=
\n",
    m_shader_core_properties.compute_units_per_shader_array =3D
    shader_core_properties.computeUnitsPerShaderArray;
printf("Number of SIMDs per compute unit: %d\n",
    m_shader_core_properties.simd_per_compute_unit =3D
    shader_core_properties.simdPerComputeUnit;
printf("Number of wavefront slots in each SIMD: %d\n",
    m_shader_core_properties.wavefronts_per_simd =3D
    shader_core_properties.wavefrontsPerSimd;
printf("Number of threads per wavefront: %d\n",
    m_shader_core_properties.wavefront_size =3D
    shader_core_properties.wavefrontSize;
printf("Number of physical SGPRs per SIMD: %d\n",
    m_shader_core_properties.sgprs_per_simd =3D
    shader_core_properties.sgprsPerSimd;
printf("Minimum number of SGPRs that can be allocated by a wave: %d\n"=
,
    m_shader_core_properties.min_sgpr_allocation =3D
    shader_core_properties.minSgprAllocation;
printf("Number of available SGPRs: %d\n",
    m_shader_core_properties.max_sgpr_allocation =3D
    shader_core_properties.maxSgprAllocation;
printf("SGPRs are allocated in groups of this size: %d\n",
    m_shader_core_properties.sgpr_allocation_granularity =3D
    shader_core_properties.sgprAllocationGranularity;
printf("Number of physical VGPRs per SIMD: %d\n",
    m_shader_core_properties.vgprs_per_simd =3D
    shader_core_properties.vgprsPerSimd;
printf("Minimum number of VGPRs that can be allocated by a wave: %d\n"=
,
    m_shader_core_properties.min_vgpr_allocation =3D
    shader_core_properties.minVgprAllocation;
printf("Number of available VGPRs: %d\n",
    m_shader_core_properties.max_vgpr_allocation =3D
    shader_core_properties.maxVgprAllocation;
printf("VGPRs are allocated in groups of this size: %d\n",
    m_shader_core_properties.vgpr_allocation_granularity =3D
    shader_core_properties.vgprAllocationGranularity;

Version History

  • Revision 1, 2018-02-15 (Martin Dinkov)

    • Initial draft.

VK_AMD_shader_explicit_v= ertex_parameter

Name String

VK_AMD_shader_explicit_vertex_parameter

Extension Type

Device extension

Registered Extension Number

22

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Qun Lin

  • AMD @linqun

Last Modified Date

2016-05-10

IP Status

No known IP claims.

Contributors
  • Matthaeus G. Chajdas, AMD

  • Qun Lin, AMD

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Rex Xu, AMD

This extension adds support for the following SPIR-V extension in Vulkan= :

editing-note

Shouldn=E2=80=99t the SPV extension be in the Interactions and External = Dependencies block?

Version History

  • Revision 1, 2016-05-10 (Daniel Rakos)

    • Initial draft

VK_AMD_shader_fragment_mask

Name String

VK_AMD_shader_fragment_mask

Extension Type

Device extension

Registered Extension Number

138

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Aaron Hagan @AaronHaganAMD

Last Modified Date

2017-08-16

IP Status

No known IP claims.

Dependencies
Contributors
  • Aaron Hagan, AMD

  • Daniel Rakos, AMD

  • Timothy Lottes, AMD

This extension provides efficient read access to the fragment mask in compressed multisampled color surfaces. The fragment mask is a lookup table that associates color samples with colo= r fragment values.

From a shader, the fragment mask can be fetched with a call to fragmentMaskFetchAMD, which returns a single uint= where each subsequent four bits specify the color fragment index corresponding to the color sample, starting from the least significant bit. For example, when eight color samples are used, the color fragment index fo= r color sample 0 will be in bits 0-3 of the fragment mask, for color sample 7 the index will be in bits 28-31.

The color fragment for a particular color sample may then be fetched wit= h the corresponding fragment mask value using the fragmentFetchAMD shader function.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New SPIR-V Capabilities

New Structures

None.

New Functions

None.

Examples

This example shows a shader that queries the fragment mask from a multisampled compressed surface and uses it to query fragment values.

#version 450 core

#extension GL_AMD_shader_fragment_mask:=
 enable

layout(binding =3D 0) uniform sampler2DMS   =
    s2DMS;
layout(binding =3D 1) uniform isampler2DMSAr=
ray is2DMSArray;

layout(binding =3D 2, input_attachment_index=
 =3D 0) uniform usubpassInputMS usubpassMS;

layout(location =3D 0) out vec4 fragColor;

void main()
{
    vec4 fragOne =3D vec4(0.0);

    uint fragMask =3D fragmentMaskFetchAMD(s2DMS, ivec2(2, 3));
    uint fragIndex =3D (fragMask & 0xF0) >=
;> 4;
    fragOne +=3D fragmentFetchAMD(s2DMS, ivec2(2, 3), 1);

    fragMask =3D fragmentMaskFetchAMD(is2DMSArray, ivec3(2, 3, 1=
));
    fragIndex =3D (fragMask & 0xF0) >>=
 4;
    fragOne +=3D fragmentFetchAMD(is2DMSArray, ivec3(2, 3, 1), fragIndex);

    fragMask =3D fragmentMaskFetchAMD(usubpassMS);
    fragIndex =3D (fragMask & 0xF0) >>=
 4;
    fragOne +=3D fragmentFetchAMD(usubpassMS, fragIndex);

    fragColor =3D fragOne;
}

Version History

  • Revision 1, 2017-08-16 (Aaron Hagan)

    • Initial draft

VK_AMD_shader_image_load_stor= e_lod

Name String

VK_AMD_shader_image_load_store_lod

Extension Type

Device extension

Registered Extension Number

47

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Dominik Witczak @dominikwitczakamd

Last Modified Date

2017-08-21

Interactions and External Dependencies
IP Status

No known IP claims.

Contributors
  • Dominik Witczak, AMD

  • Qun Lin, AMD

  • Rex Xu, AMD

This extension adds support for the following SPIR-V extension in Vulkan= :

Version History

  • Revision 1, 2017-08-21 (Dominik Witczak)

    • Initial draft

VK_AMD_shader_info

Name String

VK_AMD_shader_info

Extension Type

Device extension

Registered Extension Number

43

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Jaakko Konttinen @jaakkoamd

Last Modified Date

2017-10-09

IP Status

No known IP claims.

Contributors
  • Jaakko Konttinen, AMD

This extension adds a way to query certain information about a compiled shader which is part of a pipeline. This information may include shader disassembly, shader binary and various statistics about a shader=E2=80=99s resource usage.

While this extension provides a mechanism for extracting this informatio= n, the details regarding the contents or format of this information are not specified by this extension and may be provided by the vendor externally.

Furthermore, all information types are optionally supported, and users should not assume every implementation supports querying every type of information.

New Object Types

None.

New Enum Constants

None.

New Structures

New Functions

Examples

This example extracts the register usage of a fragment shader within a particular graphics pipeline:

extern VkDevice device;
extern VkPipeline gfxPipeline;

PFN_vkGetShaderInfoAMD pfnGetShaderInfoAMD =3D (PFN_vkGetShaderInfoAMD)vkGe=
tDeviceProcAddr(
    device, "vkGetShaderInfoAMD");

VkShaderStatisticsInfoAMD statistics =3D {};

size_t dataSize =3D sizeof(statistics);

if (pfnGetShaderInfoAMD(device,
    gfxPipeline,
    VK_SHADER_STAGE_FRAGMENT_BIT,
    VK_SHADER_INFO_TYPE_STATISTICS_AMD,
    &dataSize,
    &statistics) =3D=3D VK_SUCCESS)
{
    printf("VGPR usage: %d\n", statistics.resourceUsage.numUsedVgprs);
    printf("SGPR usage: %d\n", statistics.resourceUsage.numUsedSgprs);
}

The following example continues the previous example by subsequently attempting to query and print shader disassembly about the fragment shader:=

// Query disassembly size (if available)
if (pfnGetShaderInfoAMD(device,
    gfxPipeline,
    VK_SHADER_STAGE_FRAGMENT_BIT,
    VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD,
    &dataSize,
    nullptr) =3D=3D VK_SUCCESS)
{
    printf("Fragment shader disassembly:\n=
");

    void* disassembly =3D malloc(dataSize)=
;

    // Query disassembly and print
    if (pfnGetShaderInfoAMD(device,
        gfxPipeline,
        VK_SHADER_STAGE_FRAGMENT_BIT,
        VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD,
        &dataSize,
        disassembly) =3D=3D VK_SUCCESS)
    {
        printf((char*)disassembly);
    }

    free(disassembly);
}

Version History

  • Revision 1, 2017-10-09 (Jaakko Konttinen)

    • Initial revision

VK_AMD_shader_trinary_minmax

Name String

VK_AMD_shader_trinary_minmax

Extension Type

Device extension

Registered Extension Number

21

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Qun Lin

  • AMD @linqun

Last Modified Date

2016-05-10

IP Status

No known IP claims.

Contributors
  • Matthaeus G. Chajdas, AMD

  • Qun Lin, AMD

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Rex Xu, AMD

This extension adds support for the following SPIR-V extension in Vulkan= :

editing-note

Shouldn=E2=80=99t the SPV extension be in the Interactions and External = Dependencies block?

Version History

  • Revision 1, 2016-05-10 (Daniel Rakos)

    • Initial draft

VK_AMD_texture_gather_bias_lod
Name String

VK_AMD_texture_gather_bias_lod

Extension Type

Device extension

Registered Extension Number

42

Revision

1

Extension and Version Dependencies
Contact
  • Rex Xu @amdrexu

Last Modified Date

2017-03-21

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Dominik Witczak, AMD

  • Daniel Rakos, AMD

  • Graham Sellers, AMD

  • Matthaeus G. Chajdas, AMD

  • Qun Lin, AMD

  • Rex Xu, AMD

  • Timothy Lottes, AMD

This extension adds two related features.

Firstly, support for the following SPIR-V extension in Vulkan is added:<= /p>

  • SPV_AMD_texture_gather_bias_lod

Secondly, the extension allows the application to query which formats ca= n be used together with the new function prototypes introduced by the SPIR-V extension.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD<= /p>

New Enums

None.

New SPIR-V Capabilities

New Functions

None.

Examples

struct VkTextureLODGatherFormatPropertiesAMD
{
    VkStructureType sType;
    const void*     pNext;
    VkBool32        supportsTextureGatherLODBiasAMD;
};

// ------------------------------------------------=
----------------------------------------
// How to detect if an image format can be used wit=
h the new function prototypes.
VkPhysicalDeviceImageFormatInfo2   formatInfo;
VkImageFormatProperties2           formatProps;
VkTextureLODGatherFormatPropertiesAMD textureLODGatherSupport;

textureLODGatherSupport.sType =3D VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORM=
AT_PROPERTIES_AMD;
textureLODGatherSupport.pNext =3D nullp=
tr;

formatInfo.sType  =3D VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2=
;
formatInfo.pNext  =3D nullptr;
formatInfo.format =3D ...;
formatInfo.type   =3D ...;
formatInfo.tiling =3D ...;
formatInfo.usage  =3D ...;
formatInfo.flags  =3D ...;

formatProps.sType =3D VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
formatProps.pNext =3D &textureLODGatherSupport;

vkGetPhysicalDeviceImageFormatProperties2(physical_device, &formatInfo,=
 &formatProps);

if (textureLODGatherSupport.supportsTextureG=
atherLODBiasAMD =3D=3D VK_TRUE)
{
    // physical device supports SPV_AMD_texture_gat=
her_bias_lod for the specified
    // format configuration.
}
else
{
    // physical device does not support SPV_AMD_tex=
ture_gather_bias_lod for the
    // specified format configuration.
}

Version History

  • Revision 1, 2017-03-21 (Dominik Witczak)

    • Initial draft

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID

    • VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID

    • VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROI= D

    • VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID

    • VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID<= /code>

    • VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID

  • Extending VkExternalMemoryHandleTypeFlagBits:

    • VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID=

New Enums

None.

Issues

1) Other external memory objects are represented as weakly-typed handles (e.g. Win32 HANDLE or POSIX file descriptor), and require a ha= ndle type parameter along with handles. AHardwareBuffer is strongly typed, so naming the handle type i= s redundant. Does symmetry justify adding handle type parameters/fields anyway?

RESOLVED: No. The handle type is already provided in places that treat external memory objects generically. In the places we would add it, the application code that would have to provide the handle type value is already dealing with AHardwareBuffer-specific commands/structures; the extra symmet= ry would not be enough to make that code generic.

2) The internal layout and therefore size of a AHardwareBuffer image may depend on native usage flags that do not have corresponding Vulkan counterparts. Do we provide this info to vkCreateImage somehow, or all= ow the allocation size reported by vkGetImageMemoryR= equirements to be approximate?

RESOLVED: Allow the allocation size to be unspecified w= hen allocating the memory. It has to work this way for exported image memory anyway, since AHardwareBuffer allocation happens in vkAllo= cateMemory, and internally is performed by a separate HAL, not the Vulkan implementation itself. There is a similar issue with vkGetImageSubres= ourceLayout: the layout is determined by the allocator HAL, so it is not known until the image is bound to memory.

3) Should the result of sampling an external-format image with the sugge= sted Y=E2=80=99CbCr conversion parameters yield the same r= esults as using a samplerExternalOES in OpenGL ES?

RESOLVED: This would be desirable, so that apps convert= ing from OpenGL ES to Vulkan could get the same output given the same input. But since sampling and conversion from Y=E2=80=99CbCr= images is so loosely defined in OpenGL ES, multiple implementations do it in a way that doesn=E2= =80=99t conform to Vulkan=E2=80=99s requirements. Modifying the OpenGL ES implementation would be difficult, and would change the output of existing unmodified applications. Changing the output only for applications that are being modified gives developers the chance to notice and mitigate any problems. Implementations are encouraged to minimize differences as much as possible without causing compatibility problems for existing OpenGL ES applications or violating Vulkan requirements.

4) Should an AHardwareBuffer with AHARDWAREBUFFER_USA= GE_CPU_* usage be mappable in Vulkan? Should it be possible to export an AHardwareBuffers with such usage?

RESOLVED: Optional, and mapping in Vulkan is not the sa= me as AHardwareBuffer_lock. The semantics of these are different: mapping in memory is persistent, just gives a raw view of the memory contents, and does not involve ownership. AHardwareBuffer_lock gives the host exclusive access to the bu= ffer, is temporary, and allows for reformatting copy-in/copy-out. Implementations are not required to support host-visible memory types for imported Android hardware buffers or resources backed by them. If a host-visible memory type is supported and used, the memory can be mapped in Vulkan, but doing so follows Vulkan semantics: it is just a raw view of the data and does not imply ownership (this means implementations must not internally call AHardwareBuffer_lock to implement vkMapMemory, or assume the application has done so). Implementations are not required to support linear-tiled images backed by Android hardware buffers, even if the AHardwareBuffer has CPU = usage. There is no reliable way to allocate memory in Vulkan that can be exported to a AHardwareBuffer with CPU usage.

5) Android may add new AHardwareBuffer formats and usage fl= ags over time. Can reference to them be added to this extension, or do they need a new extension?

RESOLVED: This extension can document the interaction between the new AH= B formats/usages and existing Vulkan features. No new Vulkan features or implementation requirements can be added. The extension version number will be incremented when this additional documentation is added, but the version number does not indicate that an implementaiton supports Vulkan memory or resources that map to the new AHardwareBuffer features: support for that must be queried wit= h vkGetPhysicalDeviceImageFormatPr= operties2 or is implied by successfully allocating a AHardwareBuffer outside of Vulkan th= at uses the new feature and has a GPU usage flag.

In essence, these are new features added to a new Android API level, rat= her than new Vulkan features. The extension will only document how existing Vulkan features map to that new Android feature.

VK_GOOGLE_display_timing

Name String

VK_GOOGLE_display_timing

Extension Type

Device extension

Registered Extension Number

93

Revision

1

Extension and Version Dependencies
Contact
  • Ian Elliott @ianelliottus

Last Modified Date

2017-02-14

IP Status

No known IP claims.

Contributors
  • Ian Elliott, Google

  • Jesse Hall, Google

This device extension allows an application that uses the VK_KHR_swapchain extension to obtain inf= ormation about the presentation engine=E2=80=99s display, to obtain timing information about e= ach present, and to schedule a present to happen no earlier than a desired time= . An application can use this to minimize various visual anomalies (e.g. stuttering).

Traditional game and real-time animation applications need to correctly position their geometry for when the presentable image will be presented to the user. To accomplish this, applications need various timing information about the presentation engine=E2=80=99s display. They need to know when presentable images were actually presented, and when they could have been presented. Applications also need to tell the presentation engine to display an image no sooner than a given time. This allows the application to avoid stuttering, so the animation looks smooth to the user.

This extension treats variable-refresh-rate (VRR) displays as if they ar= e fixed-refresh-rate (FRR) displays.

New Object Types

None.

New Enum Constants

New Enums

None.

Issues

None.

Examples

Note

The example code for the this extension (like the = VK_KHR_surface and VK_GOOGLE_display_timing extensions) is contained in the cube = demo that is shipped with the official Khronos SDK, and is being kept up-to-date in that location (see: https://github.com/KhronosGroup/Vulkan-Tools/blob/mast= er/cube/cube.c ).

Version History

  • Revision 1, 2017-02-14 (Ian Elliott)

    • Internal revisions

VK_IMG_filter_cubic

Name String

VK_IMG_filter_cubic

Extension Type

Device extension

Registered Extension Number

16

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Tobias Hector @tobski

Last Modified Date

2016-02-23

Contributors
  • Tobias Hector, Imagination Technologies

VK_IMG_filter_cubic adds an additional, high quality cubic = filtering mode to Vulkan, using a Catmull-Rom bicubic filter. Performing this kind of filtering can be done in a shader by using 16 samples and a number of instructions, but this can be inefficient. The cubic filter mode exposes an optimized high quality texture sampling using fixed texture sampling functionality.

New Enum Constants

Example

Creating a sampler with the new filter for both magnification and minification

    VkSamplerCreat=
eInfo createInfo =3D
    {
        VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO // sT=
ype
        // Other members set to application-desired=
 values
    };

    createInfo.magFilter =3D VK_FILTER_CUBIC_IMG;
    createInfo.minFilter =3D VK_FILTER_CUBIC_IMG;

    VkSampler sampler;
    VkResult result =3D vkCreateSampler(
        device,
        &createInfo,
        &sampler);

Version History

  • Revision 1, 2016-02-23 (Tobias Hector)

    • Initial version

VK_MVK_ios_surface

Name String

VK_MVK_ios_surface

Extension Type

Instance extension

Registered Extension Number

123

Revision

2

Extension and Version Dependencies
Contact
  • Bill Hollings @billhollings

Last Modified Date

2017-02-24

IP Status

No known IP claims.

Contributors
  • Bill Hollings, The Brenwill Workshop Ltd.

The VK_MVK_ios_surface extension is an instance extension. It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) that refers = to a UIView, the native surface type of iOS, which is underpinned by a CAMetalLayer, t= o support rendering to the surface using Apple=E2=80=99s Metal framework.

New Object Types

None.

New Enum Constants

New Enums

None.

New Structures

New Functions

Issues

None.

Version History

  • Revision 1, 2017-02-15 (Bill Hollings)

    • Initial draft.

  • Revision 2, 2017-02-24 (Bill Hollings)

    • Minor syntax fix to emphasize firm requirement for UIView to be backed by a CAMetalLayer.

VK_MVK_macos_surface

Name String

VK_MVK_macos_surface

Extension Type

Instance extension

Registered Extension Number

124

Revision

2

Extension and Version Dependencies
Contact
  • Bill Hollings @billhollings

Last Modified Date

2017-02-24

IP Status

No known IP claims.

Contributors
  • Bill Hollings, The Brenwill Workshop Ltd.

The VK_MVK_macos_surface extension is an instance extension= . It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) that refers = to an NSView, the native surface type of macOS, which is underpinned by a CAMetalLayer<= /code>, to support rendering to the surface using Apple=E2=80=99s Metal framework.<= /p>

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK

New Enums

None.

New Functions

Issues

None.

Version History

  • Revision 1, 2017-02-15 (Bill Hollings)

    • Initial draft.

  • Revision 2, 2017-02-24 (Bill Hollings)

    • Minor syntax fix to emphasize firm requirement for NSView to be backed by a CAMetalLayer.

VK_NN_vi_surface

Name String

VK_NN_vi_surface

Extension Type

Instance extension

Registered Extension Number

63

Revision

1

Extension and Version Dependencies
Contact
  • Mathias Heyer gitlab:@mheyer

Last Modified Date

2016-12-02

IP Status

No known IP claims.

Contributors
  • Mathias Heyer, NVIDIA

  • Michael Chock, NVIDIA

  • Yasuhiro Yoshioka, Nintendo

  • Daniel Koch, NVIDIA

The VK_NN_vi_surface extension is an instance extension. It provides a mechanism to create a VkSurfaceKHR object (= defined by the VK_KHR_surface extension) associated w= ith an nn::vi::Layer.

New Object Types

None

New Enum Constants

New Enums

None

New Structures

New Functions

Issues

1) Does VI need a way to query for compatibility between a particular physical device (and queue family?) and a specific VI display?

RESOLVED: No. It is currently always assumed that the device and display will always be compatible.

2) VkViSurfaceCreateInfoNN::pWindow is intended to store an nn::vi::NativeWindowHandle, but its = declared type is a bare void* to store the window handle. Why the discrepancy?

RESOLVED: It is for C compatibility. The definition for the VI native window handle type is defined inside the nn::vi C++ namespace. This prevents its use in C source files. nn::vi::NativeWindowHandle is always= defined to be void*, so this extension uses void* to match.

Version History

  • Revision 1, 2016-12-2 (Michael Chock)

    • Initial draft.

VK_NVX_device_generated_command= s

Name String

VK_NVX_device_generated_commands

Extension Type

Device extension

Registered Extension Number

87

Revision

3

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Christoph Kubisch @pixeljetstream

Last Modified Date

2017-07-25

Contributors
  • Pierre Boudier, NVIDIA

  • Christoph Kubisch, NVIDIA

  • Mathias Schott, NVIDIA

  • Jeff Bolz, NVIDIA

  • Eric Werness, NVIDIA

  • Detlef Roettger, NVIDIA

  • Daniel Koch, NVIDIA

  • Chris Hebert, NVIDIA

This extension allows the device to generate a number of critical comman= ds for command buffers.

When rendering a large number of objects, the device can be leveraged to implement a number of critical functions, like updating matrices, or implementing occlusion culling, frustum culling, front to back sorting, etc= . Implementing those on the device does not require any special extension, since an application is free to define its own data structure, and just process them using shaders.

However, if the application desires to quickly kick off the rendering of= the final stream of objects, then unextended Vulkan forces the application to read back the processed stream and issue graphics command from the host. For very large scenes, the synchronization overhead, and cost to generate the command buffer can become the bottleneck. This extension allows an application to generate a device side stream of state changes and commands, and convert it efficiently into a command buffe= r without having to read it back on the host.

Furthermore, it allows incremental changes to such command buffers by manipulating only partial sections of a command stream=E2=80=89=E2=80=94=E2= =80=89for example pipeline bindings. Unextended Vulkan requires re-creation of entire command buffers in such scenario, or updates synchronized on the host.

The intended usage for this extension is for the application to:

  • create its objects as in unextended Vulkan

  • create a VkObjectTableNVX, and register the variou= s Vulkan objects that are needed to evaluate the input parameters.

  • create a VkIndirectCommandsLayoutNVX, w= hich lists the VkIndirectCommandsTokenTypeNVX it wants= to dynamically change as atomic command sequence. This step likely involves some internal device code compilation, since the intent is for the GPU to generate the command buffer in the pipeline.

  • fill the input buffers with the data for each of the inputs it needs. Each input is an array that will be filled with an index in the object table, instead of using CPU pointers.

  • set up a target secondary command buffer

  • reserve command buffer space via vkCmdR= eserveSpaceForCommandsNVX in a target command buffer at the position you want the generated commands to be executed.

  • call vkCmdProcessCommandsNVX to create the = actual device commands for all sequences based on the array contents into a provided target command buffer.

  • execute the target command buffer like a regular secondary command buffer

For each draw/dispatch, the following can be specified:

  • a different pipeline state object

  • a number of descriptor sets, with dynamic offsets

  • a number of vertex buffer bindings, with an optional dynamic offset

  • a different index buffer, with an optional dynamic offset

Applications should register a small n= umber of objects, and use dynamic offsets whenever possible.

While the GPU can be faster than a CPU to generate the commands, it may = not happen asynchronously, therefore the primary use-case is generating =E2=80= =9Cless=E2=80=9D total work (occlusion culling, classification to use specialized shaders, etc.).

New Enum Constants

Extending VkStructureType:

  • VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX

  • VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX<= /p>

  • VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX

  • VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX

  • VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX

  • VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX

  • VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX

Extending VkAccessFlagBits:

  • VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX

  • VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX

Issues

1) How to name this extension ?

RESOLVED: VK_NVX_device_generated_commands=

As usual, one of the hardest issues ;)

Alternatives: VK_gpu_commands, VK_execute_commands, VK_device_commands, VK_device_execute_commands, <= code>VK_device_execute, VK_device_created_commands, VK_device_recorded_commands<= /code>, VK_device_generated_commands

2) Should we use serial tokens or redundant sequence description?

Similarly to VkPipeline, signatures have the most likeli= hood to be cross-vendor adoptable. They also benefit from being processable in parallel.

3) How to name sequence description

ExecuteCommandSignature is a bit long. Maybe just ExecuteSignature, or actually more following Vulkan nomenclature: VkIndirectCommandsLayoutNVX.=

4) Do we want to provide indirectCommands inputs with layou= t or at indirectCommands time?

Separate layout from data as Vulkan does. Provide full flexibilty for indirectCommands.

5) Should the input be provided as SoA or AoS?

It is desirable for the application to reuse the list of objects and ren= der them with some kind of an override. This can be done by just selecting a different input for a push constant or a descriptor set, if they are defined as independent arrays. If the data was interleaved, this would not be as easily possible.

Allowing input divisors can also reduce the conservative command buffer allocation.

6) How do we know the size of the GPU command buffer generated by vkCmdProcessCommandsNVX ?

maxSequenceCount can give an upper estimate, even if the ac= tual count is sourced from the gpu buffer at (buffer, countOffset). As such maxSequenceCount must always be set correctly.

Developers are encouraged to make well use the VkIndirectCommandsLayoutNVX=E2=80=99s pTokens[].divisor, as they allow less conservative storage costs. Especially pipeline changes on a per-draw basis can be costly memory wise.<= /p>

7) How to deal with dynamic offsets in DescriptorSets?

Maybe additional token VK_EXECUTE_DESCRIPTOR_SET_OFFSET_COMMAND_NV= X that works for a =E2=80=9Csingle dynamic buffer=E2=80=9D descriptor set and= then use (32 bit tableEntry + 32bit offset)

added dynamicCount field, variable sized input

8) Should we allow updates to the object table, similar to DescriptorSet= ?

Desired yes, people may change =E2=80=9Cmaterial=E2=80=9D shaders and no= t want to recreate the entire register table. However the developer must ensure to not overwrite a registered objectIndex while it is still being used.

9) Should we allow dynamic state changes?

Seems a bit excessive for =E2=80=9Cper-draw=E2=80=9D type of scenario, b= ut GPU could partition work itself with viewport/scissor=E2=80=A6=E2=80=8B

10) How do we allow re-using already =E2=80=9Cfilled=E2=80=9D indi= rectCommands buffers?

just use a VkCommandBuffer for the output, and it c= an be reused easily.

11) How portable should such re-use be?

Same as secondary command buffer

12) Should sequenceOrdered be part of IndirectCommandsLayout or vkCmdProcessCommandsNVX?

Seems better for IndirectCommandsLayout, as that is when most heavy lift= ing in terms of internal device code generation is done.

13) Under which conditions is vkCmdProcessComma= ndsNVX legal?

Options:

a) on the host command buffer like a regular draw call

c) The targetCommandbuffer must be inside the =E2=80=9Cbegi= n=E2=80=9D state already at the moment of being passed. This very likely suggests a new VkCommandBuff= erUsageFlags VK_COMMAND_BUFFER_USAGE_DEVICE_GENERATED_BIT.

d) The targetCommandbuffer must reserve space via a new fun= ction.

used a) and d).

14) What if different pipelines have different DescriptorSetLayouts at a certain set unit that mismatches in token.dynamicCount?

Considered legal, as long as the maximum dynamic count of all used DescriptorSetLayouts is provided.

15) Should we add =E2=80=9Cstrides=E2=80=9D to input arrays, so that =E2= =80=9CArray of Structures=E2=80=9D type setups can be supported more easily?

Maybe provide a usage flag for packed tokens stream (all inputs from sam= e buffer, implicit stride).

No, given performance test was worse.

16) Should we allow re-using the target command buffer directly, without need to reset command buffer?

17) Is vkCmdProcessCommandsNVX copying the = input data or referencing it ?

There are multiple implementations possible:

  • one could have some emulation code that parse the inputs, and generates an output command buffer, therefore copying the inputs.

  • one could just reference the inputs, and have the processing done in pipe at execution time.

If the data is mandated to be copied, then it puts a penalty on implementation that could process the inputs directly in pipe. If the data is =E2=80=9Creferenced=E2=80=9D, then it allows both types of i= mplementation

The inputs are =E2=80=9Creferenced=E2=80=9D, and should not be modified = after the call to vkCmdProcessCommandsNVX and until after the re= ndering of the target command buffer is finished.

18) Why is this NVX and not NV?

To allow early experimentation and feedback. We expect that a version with a refined design as multi-vendor variant will follow up.

19) Should we make the availability for each token type a device limit?<= /p>

Only distinguish between graphics/compute for now, further splitting up = may lead to too much fractioning.

20) When can the objectTable be modified?

Similar to the other inputs for vkCmdProcessCom= mandsNVX, only when all device access via vkCmdProcessCommandsNVX or e= xecution of target command buffer has completed can an object at a given objectIndex be unregistered or re-registered again.

21) Which buffer usage flags are required for the buffers referenced by vkCmdProcessCommandsNVX

reuse existing VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT

22) In which pipeline stage do the device generated command expansion happen?

vkCmdProcessCommandsNVX is treated as if it= occurs in a separate logical pipeline from either graphics or compute, and that pipeline only includes VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, a new stage VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, and VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT. This new stage has two corresponding new access types, VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX and VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX, used to synchronize r= eading the buffer inputs and writing the command buffer memory output. The output written in the target command buffer is considered to be consume= d by the VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT pipeline stage.

Thus, to synchronize from writing the input buffers to executing vkCmdProcessCommandsNVX, use:

  • dstStageMask =3D VK_PIPELINE_STAGE_COMMAND_PROCESS_BI= T_NVX

  • dstAccessMask =3D VK_ACCESS_COMMAND_PROCESS_READ_BIT_= NVX

To synchronize from executing vkCmdProcessComma= ndsNVX to executing the generated commands, use

  • srcStageMask =3D VK_PIPELINE_STAGE_COMMAND_PROCESS_BI= T_NVX

  • srcAccessMask =3D VK_ACCESS_COMMAND_PROCESS_WRITE_BIT= _NVX

  • dstStageMask =3D VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT<= /code>

  • dstAccessMask =3D VK_ACCESS_INDIRECT_COMMAND_READ_BIT=

When vkCmdProcessCommandsNVX is used with a= targetCommandBuffer of NULL, the generated commands are immediately executed and t= here is implicit synchronization between generation and execution.

23) What if most token data is =E2=80=9Cstatic=E2=80=9D, but we frequent= ly want to render a subsection?

added =E2=80=9CsequencesIndexBuffer=E2=80=9D. This allows to easier sort and filter what should actually be processed.

Example Code

Open-Source samples illustrating the usage of the extension can be found= at the following locations:

  // setup secondary command buffer
    vkBeginCommandBuffer(generatedCmdBuffer, &beginInfo);
    ... setup its state as usual

  // insert the reservation (there can only be one =
per command buffer)
  // where the generated calls should be filled int=
o
    VkCmdReserveSpaceForCommandsInfoNVX reserveInfo =3D { VK_STRUCTURE_TYPE=
_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX };
    reserveInfo.objectTable =3D objectTable;
    reserveInfo.indirectCommandsLayout =3D deviceGeneratedLayout;
    reserveInfo.maxSequencesCount =3D myCount;
    vkCmdReserveSpaceForCommandsNVX(generatedCmdBuffer, &reserveInfo);

    vkEndCommandBuffer(generatedCmdBuffer);

  // trigger the generation at some point in anothe=
r primary command buffer
    VkCmdProcessCommandsInfoNVX processInfo =3D { VK_STRUCTURE_TYPE_CMD_PRO=
CESS_COMMANDS_INFO_NVX };
    processInfo.objectTable =3D objectTable;
    processInfo.indirectCommandsLayout =3D deviceGeneratedLayout;
    processInfo.maxSequencesCount =3D myCount;
    // set the target of the generation (if null we=
 would directly execute with mainCmd)
    processInfo.targetCommandBuffer =3D generatedCmdBuffer;
    // provide input data
    processInfo.indirectCommandsTokenCount =3D 3;
    processInfo.pIndirectCommandsTokens =3D myTokens;

  // If you modify the input buffer data referenced=
 by VkCmdProcessCommandsInfoNVX,
  // ensure you have added the appropriate barriers=
 prior generation process.
  // When regenerating the content of the same rese=
rved space, ensure prior operations have completed

    VkMemoryBarrier memoryBarrier =3D { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
    memoryBarrier.srcAccessMask =3D ...;
    memoryBarrier.dstAccessMask =3D VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX;

    vkCmdPipelineBarrier(mainCmd,
                         /*srcStageMask*/VK_=
PIPELINE_STAGE_ALL_COMMANDS_BIT,
                         /*dstStageMask*/VK_=
PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX,
                         /*dependencyFlags*/=
0,
                         /*memoryBarrierCount*/1,
                         /*pMemoryBarriers*/=
&memoryBarrier,
                         ...);

    vkCmdProcessCommandsNVX(mainCmd, &processInfo);
    ...
  // execute the secondary command buffer and ensur=
e the processing that modifies command-buffer content
  // has completed

    memoryBarrier.srcAccessMask =3D VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX=
;
    memoryBarrier.dstAccessMask =3D VK_ACCESS_INDIRECT_COMMAND_READ_BIT;

    vkCmdPipelineBarrier(mainCmd,
                         /*srcStageMask*/VK_=
PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX,
                         /*dstStageMask*/VK_=
PIPELINE_STAGE_DRAW_INDIRECT_BIT,
                         /*dependencyFlags*/=
0,
                         /*memoryBarrierCount*/1,
                         /*pMemoryBarriers*/=
&memoryBarrier,
                         ...)
    vkCmdExecuteCommands(mainCmd, 1, &ge=
neratedCmdBuffer);

Version History

  • Revision 3, 2017-07-25 (Chris Hebert)

    • Correction to specification of dynamicCount for push_constant token in VkIndirectCommandsLayoutNVX. Stride was incorrectly computed as dynamicCount was not treated as byte size.

  • Revision 2, 2017-06-01 (Christoph Kubisch)

    • header compatibility break: add missing _TYPE to VkIndirectCommandsTokenTypeNVX and VkObjectEntryTypeNVX enums to follow Vulkan naming convention

    • behavior clarification: only allow a single work provoking token per sequence when creating a VkIndirectCommandsLay= outNVX

  • Revision 1, 2016-10-31 (Christoph Kubisch)

    • Initial draft

VK_NVX_multiview_per_view_a= ttributes

Name String

VK_NVX_multiview_per_view_attributes

Extension Type

Device extension

Registered Extension Number

98

Revision

1

Extension and Version Dependencies
Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-01-13

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Jeff Bolz, NVIDIA

  • Daniel Koch, NVIDIA

This extension adds a new way to write shaders to be used with multiview subpasses, where the attributes for all views are written out by a single invocation of the vertex processing stages. Related SPIR-V and GLSL extensions SPV_NVX_multiview_per_view_attributes and GL_NVX_multiview_per_view_attributes introduce per-view position and viewport mask attributes arrays, and this extension defines how those per-view attribute arrays are interpreted by Vulkan. Pipelines using per-view attributes may o= nly execute the vertex processing stages once for all views rather than once per-view, which reduces redundan= t shading work.

A subpass creation flag controls whether the subpass uses this extension= . A subpass must either exclusively use thi= s extension or not use it at all.

Some Vulkan implementations only support the position attribute varying between views in the X component. A subpass can declare via a second creation flag whether all pipelines compiled for this subpass will obey this restriction.

Shaders that use the new per-view outputs (e.g. gl_PositionPerView= NV) must also write the non-per-view output (= gl_Position), and the values written must be such that gl_Positi= on =3D gl_PositionPerViewNV[gl_ViewIndex] for all views in the subpass. Implementations are free to either use the per-view outputs or the non-per-view outputs, whichever would be more efficient.

If VK_NV_viewport_array2 is not = also supported and enabled, the per-view viewport mask must not be used.<= /p>

New Object Types

None.

New Enum Constants

  • Extending VkStructureType

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PR= OPERTIES_NVX

  • Extending VkSubpassDescriptionFlagBits=

    • VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX

    • VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX

New Enums

None.

New Functions

None.

New SPIR-V Capabilities

Issues

None.

Examples

#version 450 core

#extension GL_KHX_multiview : enable
#extension GL_NVX_multiview_per_view_at=
tributes : enable

layout(location =3D 0) in vec4 position;
layout(set =3D 0, binding =3D 0) uniform Block { mat4 mvpPerView[2]; } buf;

void main()
{
    // Output both per-view positions and gl_Positi=
on as a function
    // of gl_ViewIndex
    gl_PositionPerViewNV[0] =3D buf.mvpPerVi=
ew[0] * position;
    gl_PositionPerViewNV[1] =3D buf.mvpPerVi=
ew[1] * position;
    gl_Position =3D buf.mvpPerView[gl_ViewIndex] * position;
}

Version History

  • Revision 1, 2017-01-13 (Jeff Bolz)

    • Internal revisions

VK_NV_clip_space_w_scaling

Name String

VK_NV_clip_space_w_scaling

Extension Type

Device extension

Registered Extension Number

88

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Eric Werness @ewerness-nv

Last Modified Date

2017-02-15

Contributors
  • Eric Werness, NVIDIA

  • Kedarnath Thangudu, NVIDIA

Virtual Reality (VR) applications often involve a post-processing step t= o apply a =E2=80=9Cbarrel=E2=80=9D distortion to the rendered image to correc= t the =E2=80=9Cpincushion=E2=80=9D distortion introduced by the optics in a VR de= vice. The barrel distorted image has lower resolution along the edges compared to the center. Since the original image is rendered at high resolution, which is uniform across the complete image, a lot of pixels towards the edges do not make it to the final post-processed image.

This extension provides a mechanism to render VR scenes at a non-uniform resolution, in particular a resolution that falls linearly from the center towards the edges. This is achieved by scaling the w coordinate of t= he vertices in the clip space before perspective divide. The clip space w coordinate of the vertices can be offset as of a function of x and y coo= rdinates as follows:

w' =3D w + Ax + By

In the intended use case for viewport position scaling, an application should use a set of four viewports, one for each of the four quadrants of a Cartesian coordinate system. Each viewport is set to the dimension of the image, but is scissored to the quadrant it represents. The application should specify A and B coefficients of the w-scaling equation above, that have the same valu= e, but different signs, for each of the viewports. The signs of A and B sh= ould match the signs of x and y for the quadrant that they represent such that = the value of w' will always be greater than or equal to the original w value for the entire image. Since the offset to w, (Ax + B= y), is always positive, and increases with the absolute values of x and y, the effective resolution will fall off linearly from the center of the image to its edges= .

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV=

  • Extending VkDynamicState:

    • VK_DYANMIC_STATE_VIEWPORT_W_SCALING_NV

New Enums

None.

Issues

1) Is the pipeline struct name too long?

RESOLVED: It fits with the naming convention.

2) Separate W scaling section or fold into coordinate transformations?

RESOLVED: Leaving it as its own section for now.

Examples

VkViewport viewpor=
ts[4];
VkRect2D scissors[4];
VkViewportWScalingNV scalings[4];

for (int i =3D 0; i < =
4; i++) {
    int x =3D (i & 2) ? 0 : currentWindowWi=
dth / 2;
    int y =3D (i & 1) ? 0 : currentWindowHe=
ight / 2;

    viewports[i].x =3D 0;
    viewports[i].y =3D 0;
    viewports[i].width =3D currentWindowWidth;
    viewports[i].height =3D currentWindowHeight;
    viewports[i].minDepth =3D 0.0f;
    viewports[i].maxDepth =3D 1.0f;

    scissors[i].offset.x =3D x;
    scissors[i].offset.y =3D y;
    scissors[i].extent.width =3D currentWindowWidth/2;
    scissors[i].extent.height =3D currentWindowHeight/2;

    const =
float factor =3D 0.15;
    scalings[i].xcoeff =3D ((i & 2) ? -<=
span class=3D"float">1.0 : 1.0) * factor;
    scalings[i].ycoeff =3D ((i & 1) ? -<=
span class=3D"float">1.0 : 1.0) * factor;
}

VkPipelineViewportWScalingStateCreateInfoNV vpWScalingStateInfo =3D { VK_ST=
RUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV };

vpWScalingStateInfo.viewportWScalingEnable =3D VK_TRUE;
vpWScalingStateInfo.viewportCount =3D 4;
vpWScalingStateInfo.pViewportWScalings =3D &scalings[0];

VkPipelineViewportStateCreateInfo vpStateInfo =3D { VK_STRUCTURE_TYPE_PIPEL=
INE_VIEWPORT_STATE_CREATE_INFO };
vpStateInfo.viewportCount =3D 4;
vpStateInfo.pViewports =3D &viewports[0]=
;
vpStateInfo.scissorCount =3D 4;
vpStateInfo.pScissors =3D &scissors[0];
vpStateInfo.pNext =3D &vpWScalingStateInfo;

Example shader to read from a w-scaled texture:

// Vertex Shader
// Draw a triangle that covers the whole screen
const vec4 positions[3] =3D vec4[3](vec4(-1, -1, 0, 1),
                                  vec4( 3, -=
1, 0, 1),
                                  vec4(-1,  =
3, 0, 1));
out vec2 uv;
void main()
{
    vec4 pos =3D positions[ gl_VertexID ];
    gl_Position =3D pos;
    uv =3D pos.xy;
}

// Fragment Shader
uniform sampler2D tex;
uniform float xcoeff;
uniform float ycoeff;
out vec4 Color;
in vec2 uv;

void main()
{
    // Handle uv as if upper right quadrant
    vec2 uvabs =3D abs(uv);

    // unscale: transform w-scaled image into an un=
scaled image
    //   scale: transform unscaled image int a w-sc=
aled image
    float unscale =3D 1.0 / (=
1 + xcoeff * uvabs.x + xcoeff * uvabs.y);
    //float scale =3D 1.0 / (1 - xcoeff * uvabs.x -=
 xcoeff * uvabs.y);

    vec2 P =3D vec2(unscale * uvabs.x, unscale * uvabs.y);

    // Go back to the right quadrant
    P *=3D sign(uv);

    Color =3D texture(tex, P * 0.5 + 0.5<=
/span>);
}

Version History

  • Revision 1, 2017-02-15 (Eric Werness)

    • Internal revisions

VK_NV_device_diagnostic_chec= kpoints

Name String

VK_NV_device_diagnostic_checkpoints

Extension Type

Device extension

Registered Extension Number

207

Revision

2

Extension and Version Dependencies
Contact
  • Nuno Subtil @nsubtil

Last Modified Date

2018-07-16

Contributors
  • Oleg Kuznetsov, NVIDIA

  • Alex Dunn, NVIDIA

  • Jeff Bolz, NVIDIA

  • Eric Werness, NVIDIA

  • Daniel Koch, NVIDIA

This extension allows applications to insert markers in the command stre= am and associate them with custom data.

If a device lost error occurs, the application = may then query the implementation for the last markers to cross specific implementation-define= d pipeline stages, in order to narrow down which commands were executing at the time and might have caused the failure.

New Object Types

None.

New Enum Constants

Extending VkStructureType:

  • VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV

  • VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV

New Enums

None.

Issues

None yet!

Version History

  • Revision 1, 2018-07-16 (Nuno Subtil)

    • Internal revisions

VK_NV_fill_rectangle

Name String

VK_NV_fill_rectangle

Extension Type

Device extension

Registered Extension Number

154

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-05-22

Contributors
  • Jeff Bolz, NVIDIA

This extension adds a new VkPolygonMode enum where a triangle is rasterized by computing and filling its axis-aligned screen-space bounding box, disregarding the actual triangle edges. This can be useful for drawing a rectangle without being split into two triangles with an internal edge. It is also useful to minimize the number of primitives that need to be drawn, particularly for a user interface.

New Object Types

None.

New Enum Constants

New Enums

None.

New Structures

None.

New Functions

None.

Issues

None.

Version History

  • Revision 1, 2017-05-22 (Jeff Bolz)

    • Internal revisions

VK_NV_fragment_coverage_to_colo= r

Name String

VK_NV_fragment_coverage_to_color

Extension Type

Device extension

Registered Extension Number

150

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-05-21

Contributors
  • Jeff Bolz, NVIDIA

This extension allows the fragment coverage value, represented as an int= eger bitmask, to be substituted for a color output being written to a single-component color attachment with integer components (e.g. VK_FORMAT_R8_UINT). The functionality provided by this extension is different from simply writing the SampleMask fragment shader output, in that the cov= erage value written to the framebuffer is taken after stencil test and depth test= , as well as after fragment operations such as alpha-to-coverage.

This functionality may be useful for deferred rendering algorithms, wher= e the second pass needs to know which samples belong to which original fragments.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV<= /code>

New Functions

None.

Issues

None.

Version History

  • Revision 1, 2017-05-21 (Jeff Bolz)

    • Internal revisions

VK_NV_framebuffer_mixed_samples<= /h4>
Name String

VK_NV_framebuffer_mixed_samples

Extension Type

Device extension

Registered Extension Number

153

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-06-04

Contributors
  • Jeff Bolz, NVIDIA

This extension allows multisample rendering with a raster and depth/sten= cil sample count that is larger than the color sample count. Rasterization and the results of the depth and stencil tests together determine the portion of a pixel that is =E2=80=9Ccovered=E2=80=9D. It can be useful to evaluate coverage at a higher frequency than color samples are stored. This coverage is then =E2=80=9Creduced=E2=80=9D to a collection of covered = color samples, each having an opacity value corresponding to the fraction of the color sample covered. The opacity can optionally be blended into individual color samples.

Rendering with fewer color samples than depth/stencil samples greatly reduces the amount of memory and bandwidth consumed by the color buffer. However, converting the coverage values into opacity introduces artifacts where triangles share edges and may not b= e suitable for normal triangle mesh rendering.

One expected use case for this functionality is Stencil-then-Cover path rendering (similar to the OpenGL GL_NV_path_rendering extension). The stencil step determines the coverage (in the stencil buffer) for an entire path at the higher sample frequency, and then the cover step draws the path into the lower frequency color buffer using the coverage information to antialias path edges. With this two-step process, internal edges are fully covered when antialiasing is applied and there is no corruption on these edges.

The key features of this extension are:

  • It allows render pass and framebuffer objects to be created where the number of samples in the depth/stencil attachment in a subpass is a multiple of the number of samples in the color attachments in the subpass.

  • A coverage reduction step is added to Fragment Operations which converts a set of covered raster/depth/stencil samples to a set of color samples that perform blending and color writes. The coverage reduction step also includes an optional coverage modulation step, multiplying color values by a fractional opacity corresponding to the number of associated raster/depth/stencil samples covered.

New Object Types

None.

New Enum Constants

None.

New Functions

None.

Issues

None.

Version History

  • Revision 1, 2017-06-04 (Jeff Bolz)

    • Internal revisions

VK_NV_geometry_shader_passthro= ugh

Name String

VK_NV_geometry_shader_passthrough

Extension Type

Device extension

Registered Extension Number

96

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Koch @dgkoch

Last Modified Date

2017-02-15

Interactions and External Dependencies
Contributors
  • Piers Daniell, NVIDIA

  • Jeff Bolz, NVIDIA

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_NV_geometry_shader_passthrough

Geometry shaders provide the ability for applications to process each primitive sent through the graphics pipeline using a programmable shader. However, one common use case treats them largely as a =E2=80=9Cpassthrough= =E2=80=9D. In this use case, the bulk of the geometry shader code simply copies inputs from each vertex of the input primitive to corresponding outputs in the vertices of the output primitive. Such shaders might also compute values for additional built-in or user-defined per-primitive attributes (e.g., Layer) to be assi= gned to all the vertices of the output primitive.

This extension provides access to the PassthroughNV decorat= ion under the GeometryShaderPassthroughNV capability. Adding this to a geometry shader input variable specifies that the values o= f this input are copied to the corresponding vertex of the output primitive.<= /p>

When using GLSL source-based shading languages, the passthrough layout qualifier from GL_NV_geometry_shader_passthrough maps to the PassthroughNV decoration. To use the passthrough layout, in GLSL the GL_NV_geometry_shader_passthrough extension must be enabled. Behaviour is described in the GL_NV_geometry_shader_passthrough extension specification.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

New Built-In Variables

None.

New Variable Decoration

New SPIR-V Capabilities

Issues

1) Should we require or allow a passthrough geometry shader to specify t= he output layout qualifiers for the output primitive type and maximum vertex count in the SPIR-V?

RESOLVED: Yes they should be required in the SPIR-V. Per GL_NV_geometry_shader_passthrough they are not permitted in the GLSL source shader, but SPIR-V is lower-level. It is straightforward for the GLSL compiler to infer them from the input primitive type and to explicitly emit them in the SPIR-V according to the following table.

Input Layout Implied Output Layout

poi= nts

layout(points, max_vertices=3D1)

lin= es

layout(line_strip, max_vertices=3D2)

tri= angles

layout(triangle_strip, max_vertices=3D3)

2) How does interface matching work with passthrough geometry shaders?

RESOLVED: This is described in Passthrough Interface Matching. In GL when using passthough geometry shaders in separable mode, all inputs must also be explicitly assigned location layout qualifiers. In Vulkan all SPIR-V shader inputs (except built-ins) must also have location decorations specified. Redeclarations of built-in varables that add the passthrough layout qualifier are exempted from the rule requiring location assignment because built-in variables do not have locations and are matched by BuiltIn decoration.

Sample Code

Consider the following simple geometry shader in unextended GLSL:

layout(triangles) in=
;
layout(triangle_strip) out;
layout(max_vertices=3D3) out;

in Inputs {
    vec2 texcoord;
    vec4 baseColor;
} v_in[];
out Outputs {
    vec2 texcoord;
    vec4 baseColor;
};

void main()
{
    int layer =3D compute_layer();
    for (int=
 i =3D 0; i < 3; i++) {
        gl_Position =3D gl_in[i].gl_Position;
        texcoord =3D v_in[i].texcoord;
        baseColor =3D v_in[i].baseColor;
        gl_Layer =3D layer;
        EmitVertex();
    }
}

In this shader, the inputs gl_Position, Inputs= .texcoord, and Inputs.baseColor are simply copied from the input vertex to th= e corresponding output vertex. The only =E2=80=9Cinteresting=E2=80=9D work done by the geometry shader is = computing and emitting a gl_Layer value for the primitive.

The following geometry shader, using this extension, is equivalent:

#extension GL_NV_geometry_shader_passthrough : require

layout(triangles) in;
// No output primitive layout qualifiers required.<=
/span>

// Redeclare gl_PerVertex to pass through "gl_Posit=
ion".
layout(passthrough) in gl_PerVertex {
    vec4 gl_Position;
} gl_in[];

// Declare "Inputs" with "passthrough" to automatic=
ally copy members.
layout(passthrough) in Inputs {
    vec2 texcoord;
    vec4 baseColor;
} v_in[];

// No output block declaration required.

void main()
{
    // The shader simply computes and writes gl_Lay=
er.  We don't
    // loop over three vertices or call EmitVertex(=
).
    gl_Layer =3D compute_layer();
}

Version History

  • Revision 1, 2017-02-15 (Daniel Koch)

    • Internal revisions

VK_NV_sample_mask_override_c= overage

Name String

VK_NV_sample_mask_override_coverage

Extension Type

Device extension

Registered Extension Number

95

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Piers Daniell @pdaniell-nv

Last Modified Date

2016-12-08

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Daniel Koch, NVIDIA

  • Jeff Bolz, NVIDIA

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_NV_sample_mask_override_coverage

The extension provides access to the OverrideCoverageNV dec= oration under the SampleMaskOverrideCoverageNV capability. Adding this decoration to a variable with the SampleMask built= in decoration allows the shader to modify the coverage mask and affect which samples are used to process the fragment.

When using GLSL source-based shader languages, the override_covera= ge layout qualifier from GL_NV_sample_mask_override_coverage maps to the OverrideCoverageNV decoration. To use the override_coverage layout qualifier in GLSL the GL_NV_sample_mask_override_coverage extension must be enabled. Behavior is described in the GL_NV_sample_mask_override_coverage extension spec.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

New Built-In Variables

None.

New Variable Decoration

New SPIR-V Capabilities

Issues

None.

Version History

  • Revision 1, 2016-12-08 (Piers Daniell)

    • Internal revisions

VK_NV_shader_subgroup_partitio= ned

Name String

VK_NV_shader_subgroup_partitioned

Extension Type

Device extension

Registered Extension Number

199

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.1

Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2018-03-17

Contributors
  • Jeff Bolz, NVIDIA

This extension enables support for a new class of subgroup operations vi= a the GL_NV_shader_subgroup_partitioned GLSL extension and SPV_NV_shader_subgroup_partitioned SPIR-V extension. Support for these new operations is advertised via the VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV bit.

This extension requires Vulkan 1.1, for general subgroup support.

New Object Types

None.

New Enum Constants

New Enums

None.

New Structures

None.

New Functions

None.

Issues

None.

Version History

  • Revision 1, 2018-03-17 (Jeff Bolz)

    • Internal revisions

VK_NV_viewport_array2

Name String

VK_NV_viewport_array2

Extension Type

Device extension

Registered Extension Number

97

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Daniel Koch @dgkoch

Last Modified Date

2017-02-15

Interactions and External Dependencies
  • This extension requires the SPV_NV_viewport_array2 SPIR-V extension.

  • This extension requires the GL_NV_viewport_array2 extension for GLSL source languages.

  • This extension requires the geometryShader and multiV= iewport features.

  • This extension interacts with the tessellationShader featur= e.

Contributors
  • Piers Daniell, NVIDIA

  • Jeff Bolz, NVIDIA

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_NV_viewport_array2

which allows a single primitive to be broadcast to multiple viewports an= d/or multiple layers. A new shader built-in output ViewportMaskNV is provided, which= allows a single primitive to be output to multiple viewports simultaneously. Also, a new SPIR-V decoration is added to control whether the effective viewport index is added into the variable decorated with the Layer built-in decoration. These capabilities allow a single primitive to be output to multiple layers simultaneously.

This extension allows variables decorated with the Layer an= d ViewportIndex built-ins to be exported from vertex or tessella= tion shaders, using the ShaderViewportIndexLayerNV capability.

This extension adds a new ViewportMaskNV built-in decoratio= n that is available for output variables in vertex, tessellation evaluation, and geometry shaders, and a new ViewportRelativeNV decoration that= can be added on variables decorated with Layer when using the ShaderViewportMaskNV capability.

When using GLSL source-based shading languages, the gl_ViewportMas= k[] built-in output variable and viewport_relative layout qualifie= r from GL_NV_viewport_array2 map to the ViewportMaskNV and ViewportRelativeNV decorations, respectively. Behaviour is described in the GL_NV_viewport_array2 extension specificiation.

Note

The ShaderViewportIndexLayerNV capability is equivalent to = the ShaderViewportIndexLayerEXT capability added by VK_EXT_shader_viewport_index_laye= r.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

New or Modified Built-In V= ariables

Issues

None yet!

Version History

  • Revision 1, 2017-02-15 (Daniel Koch)

    • Internal revisions

VK_NV_viewport_swizzle

Name String

VK_NV_viewport_swizzle

Extension Type

Device extension

Registered Extension Number

99

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Contact
  • Piers Daniell @pdaniell-nv

Last Modified Date

2016-12-22

Interactions and External Dependencies
  • This extension requires multiViewport and geometrySha= der features to be useful.

Contributors
  • Daniel Koch, NVIDIA

  • Jeff Bolz, NVIDIA

This extension provides a new per-viewport swizzle that can modify the position of primitives sent to each viewport. New viewport swizzle state is added for each viewport, and a new position vector is computed for each vertex by selecting from and optionally negatin= g any of the four components of the original position vector.

This new viewport swizzle is useful for a number of algorithms, includin= g single-pass cubemap rendering (broadcasting a primitive to multiple faces and reorienting the vertex position for each face) and voxel rasterization. The per-viewport component remapping and negation provided by the swizzle allows application code to re-orient three-dimensional geometry with a view along any of the X, Y, or Z axes. If a perspective projection and depth buffering is required, 1/W buffering should be used, as described in the single-pass cubemap rendering example in the =E2=80=9CIssues=E2=80=9D section below.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV

New Functions

None.

Issues

1) Where does viewport swizzling occur in the pipeline?

RESOLVED: Despite being associated with the viewport, v= iewport swizzling must happen prior to the viewport transform. In particular, it needs to be performed before clipping and perspective division.

The viewport mask expansion (VK_NV_viewport= _array2) and the viewport swizzle could potentially be performed before or after transform feedback, but feeding back several viewports worth of primitives with different swizzles doesn=E2=80=99t seem particularly useful. This specification applies the viewport mask and swizzle after transform feedback, and makes primitive queries only count each primitive once.

2) Any interesting examples of how this extension, VK_NV_viewport_array2, and VK_NV_geometry_shader_passthrough can be used together in practice?

RESOLVED: One interesting use case for this extension i= s for single-pass rendering to a cubemap. In this example, the application would attach a cubemap texture to a layere= d FBO where the six cube faces are treated as layers. Vertices are sent through the vertex shader without applying a projection matrix, where the gl_Position output is (x,= y,z,1) and the center of the cubemap is at (0,0,0). With unextended Vulkan, one could have a conventional instanced geometry shader that looks something like the following:

layout(invocations =
=3D 6) in;     // se=
parate invocation per face
layout(triangles) in;
layout(triangle_strip) out;
layout(max_vertices =3D 3) out;

in Inputs {
vec2 texcoord;
vec3 normal;
vec4 baseColor;
} v[];

    out Outputs {
    vec2 texcoord;
    vec3 normal;
    vec4 baseColor;
    };

    void main()
    {
    int face =3D gl_InvocationID;  <=
span class=3D"comment">// which face am I?

    // Project gl_Position for each vertex onto the=
 cube map face.
    vec4 positions[3];
    for (int=
 i =3D 0; i < 3; i++) {
        positions[i] =3D rotate(gl_in[i].gl_Position, face);
    }

    // If the primitive doesn't project onto this f=
ace, we're done.
    if (shouldCull(positions)) {
        return;
    }

    // Otherwise, emit a copy of the input primitiv=
e to the
    // appropriate face (using gl_Layer).
    for (int=
 i =3D 0; i < 3; i++) {
        gl_Layer =3D face;
        gl_Position =3D positions[i];
        texcoord =3D v[i].texcoord;
        normal =3D v[i].normal;
        baseColor =3D v[i].baseColor;
        EmitVertex();
    }
}

With passthrough geometry shaders, this can be done using a much simpler shader:

layout(triangles) in=
;
layout(passthrough) in Inputs {
    vec2 texcoord;
    vec3 normal;
    vec4 baseColor;
}
layout(passthrough) in gl_PerVertex {
    vec4 gl_Position;
} gl_in[];
layout(viewport_relative) out int gl=
_Layer;

void main()
{
    // Figure out which faces the primitive project=
s onto and
    // generate a corresponding viewport mask.
    uint mask =3D 0;
    for (int=
 i =3D 0; i < 6; i++) {
        if (!shouldCull(face)) {
        mask |=3D 1U << i;
        }
    }
    gl_ViewportMask =3D mask;
    gl_Layer =3D 0;
}

The application code is set up so that each of the six cube faces has a separate viewport (numbered 0 to 5). Each face also has a separate swizzle, programmed via the VkPipelineViewportSwizzleStateC= reateInfoNV pipeline state. The viewport swizzle feature performs the coordinate transformation handled by the rotate() function in the original shader. The viewport_relative layout qualifier says that the viewport = number (0 to 5) is added to the base gl_Layer value of 0 to determine wh= ich layer (cube face) the primitive should be sent to.

Note that the use of the passed through input normal in thi= s example suggests that the fragment shader in this example would perform an operatio= n like per-fragment lighting. The viewport swizzle would transform the position to be face-relative, but normal would remain in the original coordinate system. It seems likely that the fragment shader in either version of the example would want to perform lighting in the original coordinate system. It would likely do this by reconstructing the position of the fragment in the original coordinate system using gl_FragCoord, a constant = or uniform holding the size of the cube face, and the input gl_ViewportIndex (or gl_Layer), which identifies = the cube face. Since the value of normal is in the original coordinate system= , it would not need to be modified as part of this coordinate transformation.

Note that while the rotate() operation in the regular geome= try shader above could include an arbitrary post-rotation projection matrix, the viewport swizzle does not support arbitrary math. To get proper projection, 1/W buffering should be= used. To do this:

1. Program the viewport swizzles to move the pre-projection W eye coordinate (typically 1.0) into the Z coordinate = of the swizzle output and the eye coordinate component used for depth into the W coordinate. For example, the viewport corresponding to the +Z= face might use a swizzle of (+X, -Y, +W, +Z). The Z normalized device coordinate computed after= swizzling would then be z'/w' =3D 1/Zeye.

2. On NVIDIA implementations supporting floating-point depth buffers with values outside [0,1], prevent unwanted near plane= clipping by enabling depthClampEnable. Ensure that the depth clamp doesn=E2=80=99t mess up depth testing by progra= mming the depth range to very large values, such as minDepth= Bounds=3D-z, maxDepthBounds=3D+z, where z =3D 2127. It should be possible to use IEEE infinity encodings also (0xFF800000= for -INF, 0x7F800000 for +INF). Even when near/far clipping is disabled, primitives extending behind the ey= e will still be clipped because one or more vertices will have a negative W coordinate and fail X= /Y clipping tests.

On other implementations, scale X, Y, and Z eye coordinates so that vertices on the near plane have a post-swizzle W coordinate of 1.0. For example, if the near plane is at Zeye =3D= 1/256, scale X, Y, and Z by 256.

3. Adjust depth testing to reflect the fact that 1/W= values are large near the eye and small away from the eye. Clear the depth buffer to zero (infinitely far away) and use a depth test o= f VK_COMPARE_OP_GREATER instead of VK_COMPARE_OP_LESS.

Version History

  • Revision 1, 2016-12-22 (Piers Daniell)

    • Internal revisions

List of Deprecated Extensio= ns

VK_KHR_16bit_storage

Name String

VK_KHR_16bit_storage

Extension Type

Device extension

Registered Extension Number

84

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • Jan-Harald Fredriksen @janharaldfredriksen-arm

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Alexander Galazin, ARM

  • Jan-Harald Fredriksen, ARM

  • Joerg Wagner, ARM

  • Neil Henning, Codeplay

  • Jeff Bolz, Nvidia

  • Daniel Koch, Nvidia

  • David Neto, Google

  • John Kessenich, Google

The VK_KHR_16bit_storage extension allows use of 16-bit typ= es in shader input and output interfaces, and push constant blocks. This extension introduces several new optional features which map to SPIR-V capabilities and allow access to 16-bit data in Block-decorate= d objects in the Uniform and the StorageBuffer storage clas= ses, and objects in the PushConstant storage class. This extension allows 16-bit variables to be declared and used as user-defined shader inputs and outputs but does not change location assignment and component assignment rules.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

Version History

  • Revision 1, 2017-03-23 (Alexander Galazin)

    • Initial draft

VK_KHR_bind_memory2

Name String

VK_KHR_bind_memory2

Extension Type

Device extension

Registered Extension Number

158

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Tobias Hector @tobski

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jeff Bolz, NVIDIA

  • Tobias Hector, Imagination Technologies

This extension provides versions of vkBindBufferMemo= ry and vkBindImageMemory that allow multiple bindings to be= performed at once, and are extensible.

This extension also introduces VK_IMAGE_CREATE_ALIAS_BIT_KHR, which allows =E2=80=9Cidentical=E2=80=9D images that alias the same memory to int= erpret the contents consistently, even across image layout changes.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR

    • VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR

  • Extending VkImageCreateFlagBits:

    • VK_IMAGE_CREATE_ALIAS_BIT_KHR

New Enums

None.

New Built-In Variables

None.

New SPIR-V Capabilities

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

Version History

  • Revision 1, 2017-05-19 (Tobias Hector)

    • Pulled bind memory functions into their own extension

VK_KHR_dedicated_allocation

Name String

VK_KHR_dedicated_allocation

Extension Type

Device extension

Registered Extension Number

128

Revision

3

Extension and Version Dependencies
Deprecation state
Contact
  • James Jones @cubanismo

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jeff Bolz, NVIDIA

  • Jason Ekstrand, Intel

This extension enables resources to be bound to a dedicated allocation, rather than suballocated. For any particular resource, applications can query whether a dedicated allocation is recommended, in which case using a dedicated allocation may improve the performance of access to that resource. Normal device memory allocations must support multiple resources per allocation, memory aliasing and sparse binding, which could interfere with some optimizations. Applications should query the implementation for when a dedicated allocatio= n may be beneficial by adding VkMemor= yDedicatedRequirementsKHR to the pNext chain of the VkMemoryRequirements2 structur= e passed as the pMemoryRequirements parameter to a call to vkGetBufferMemoryRequirements2 or vkGetImageMemoryRequir= ements2. Certain external handle types and external images or buffers may also depend on dedicated allocations on implementations that associate image or buffer metadata with OS-level memory objects.

This extension adds a two small structures to memory requirements queryi= ng and memory allocation: a new structure that flags whether an image/buffer should have a dedicated allocation, and a structure indicating the image or buffer that an allocation will be bound to.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR

    • VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR

New Enums

None.

New Functions

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

Examples

    // Create an image with a dedicated allocation based on the
    // implementation's preference

    VkImageCreateInfo imageCreateInfo =3D
    {
        // Image creation parameters
    };

    VkImage image;
    VkResult result =3D vkCreateImage(
        device,
        &imageCreateInfo,
        NULL,                   =
            // pAllocator
        &image);

    VkMemoryDedicatedRequirementsKHR dedicatedRequirements =3D
    {
        VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,
        NULL,                   =
            // pNext
    };

    VkMemoryRequirements2 memoryRequirements =3D
    {
        VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
        &dedicatedRequirements,             // =
pNext
    };

    const VkImageMemoryRequirementsInfo2 i=
mageRequirementsInfo =3D
    {
        VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
        NULL,                   =
            // pNext
        image
    };

    vkGetImageMemoryRequirements2(
        device,
        &imageRequirementsInfo,
        &memoryRequirements);

    if (dedicatedRequirements.prefersDedicat=
edAllocation) {
        // Allocate memory with VkMemoryDedicatedAl=
locateInfoKHR::image
        // pointing to the image we are allocating =
the memory for

        VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =3D
        {
            VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,   // sType
            NULL,               =
                                    // pNext
            image,                                                  // image
            VK_NULL_HANDLE,                                         // buffer
        };

        VkMemoryAllocateInfo memoryAllocateInfo =3D
        {
            VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,                 // sType
            &dedicatedInfo,                                         // pNext
            memoryRequirements.size,                                // allocationSize
            FindMemoryTypeIndex(memoryRequirements.memoryTypeBits), // memoryTypeIndex
        };

        VkDeviceMemory memory;
        vkAllocateMemory(
            device,
            &memoryAllocateInfo,
            NULL,               =
        // pAllocator
            &memory);

        // Bind the image to the memory

        vkBindImageMemory(
            device,
            image,
            memory,
            0);
    } else {
        // Take the normal memory sub-allocation pa=
th
    }

Version History

  • Revision 1, 2017-02-27 (James Jones)

    • Copy content from VK_NV_dedicated_allocation

    • Add some references to external object interactions to the overview.

  • Revision 2, 2017-03-27 (Jason Ekstrand)

    • Rework the extension to be query-based

  • Revision 3, 2017-07-31 (Jason Ekstrand)

    • Clarify that memory objects created with VkMemoryDedicatedAllocateInfoKHR can only have the specified resource bound and no others.

VK_KHR_descriptor_update_templ= ate

Name String

VK_KHR_descriptor_update_template

Extension Type

Device extension

Registered Extension Number

86

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Markus Tavenrath @mtavenrath

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Jeff Bolz, NVIDIA

  • Michael Worcester, Imagination Technologies

Applications may wish to update a fixed set of descriptors in a large nu= mber of descriptors sets very frequently, i.e. during initializaton phase or if it=E2=80=99s required to rebuild descriptor sets for each frame. For those cases it=E2=80=99s also not unlikely that all information require= d to update a single descriptor set is stored in a single struct. This extension provides a way to update a fixed set of descriptors in a single VkDescriptorSet with a pointer to a user define= d data structure which describes the new descriptors.

New Enum Constants

Extending VkStructureType:

  • VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR

Promotion to Vulkan 1.1

vkCmdPushDescriptorSetWithTemplat= eKHR is included as an interaction with VK_KHR_push_descriptor. If Vulkan 1.1 and VK_KHR_push_descriptor are supported, this is included by VK_KHR_push_descriptor.

The base functionality in this extension is included in core Vulkan 1.1, with the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Version History

  • Revision 1, 2016-01-11 (Markus Tavenrath)

    • Initial draft

VK_KHR_device_group

Name String

VK_KHR_device_group

Extension Type

Device extension

Registered Extension Number

61

Revision

3

Extension and Version Dependencies
Deprecation state
Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-10-06

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jeff Bolz, NVIDIA

  • Tobias Hector, Imagination Technologies

This extension provides functionality to use a logical device that consi= sts of multiple physical devices, as created with the VK_KHR_device_group_creation= extension. A device group can allocate memory across the subdevices, bind memory from one subdevice to a resource on another subdevice, record command buffers where some work executes on an arbitrary subset of the subdevices, and potentially present a swapchain image from one or more subdevices.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR

    • VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR

    • VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR

    • VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR

    • VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR

    • VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR<= /p>

    • VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR

  • Extending VkImageCreateFlagBits

    • VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR

  • Extending VkPipelineCreateFlagBits

    • VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR

    • VK_PIPELINE_CREATE_DISPATCH_BASE_KHR

  • Extending VkDependencyFlagBits

    • VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR

  • Extending VkSwapchainCreateFlagBitsKHR=

    • VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR

New Built-In Variables

New SPIR-V Capabilities

Promotion to Vulkan 1.1

The following enums, types and commands are included as interactions wit= h VK_KHR_swapchain:

If Vulkan 1.1 and VK_KHR_swapchain are supported, these are included by VK_KHR_swapchain.

The base functionality in this extension is included in core Vulkan 1.1, with the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

Examples

TODO

Version History

  • Revision 1, 2016-10-19 (Jeff Bolz)

    • Internal revisions

  • Revision 2, 2017-05-19 (Tobias Hector)

    • Removed extended memory bind functions to VK_KHR_bind_memory2, added dependency on that extension, and device-group-specific structs for those functions.

  • Revision 3, 2017-10-06 (Ian Elliott)

    • Corrected Vulkan 1.1 interactions with the WSI extensions. All Vulkan 1.1 WSI interactions are with the VK_KHR_swapchain extension.

  • Revision 4, 2017-10-10 (Jeff Bolz)

    • Rename "SFR" bits and structure members to use the phrase "split instance bind regions".

VK_KHR_device_group_creation

Name String

VK_KHR_device_group_creation

Extension Type

Instance extension

Registered Extension Number

71

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2016-10-19

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jeff Bolz, NVIDIA

This extension provides instance-level commands to enumerate groups of physical devices, and to create a logical device from a subset of one of those groups. Such a logical device can then be used with new features in the VK_KHR_device_group extension.

New Object Types

None.

New Enum Constants

New Enums

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

Examples

    VkDeviceCreate=
Info devCreateInfo =3D { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
    // (not shown) fill out devCreateInfo as usual.=

    uint32_t deviceGroupCount =3D 0;
    VkPhysicalDeviceGroupPropertiesKHR *props =3D NULL;

    // Query the number of device groups
    vkEnumeratePhysicalDeviceGroupsKHR(g_vkInstance, &deviceGroupCount,=
 NULL);

    // Allocate and initialize structures to query =
the device groups
    props =3D (VkPhysicalDeviceGroupPropertiesKHR *)malloc(deviceGroupCount=
*sizeof(VkPhysicalDeviceGroupPropertiesKHR))=
;
    for (i =3D 0; i < deviceGroupCount; ++i) {
        props[i].sType =3D VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTI=
ES_KHR;
        props[i].pNext =3D NULL;
    }
    vkEnumeratePhysicalDeviceGroupsKHR(g_vkInstance, &deviceGroupCount,=
 props);

    // If the first device group has more than one =
physical device. create
    // a logical device using all of the physical d=
evices.
    VkDeviceGroupDeviceCreateInfoKHR deviceGroupInfo =3D { VK_STRUCTURE_TYP=
E_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR };
    if (props[0].physicalDeviceCount > 1) {
        deviceGroupInfo.physicalDeviceCount =3D props[0].physicalDeviceCount;
        deviceGroupInfo.pPhysicalDevices =3D props[=
0].physicalDevices;
        devCreateInfo.pNext =3D &deviceGroupInfo;
    }

    vkCreateDevice(props[0].physicalDevices[=
0], &devCreateInfo, NULL, &g_vkDevice);
    free(props);

Version History

  • Revision 1, 2016-10-19 (Jeff Bolz)

    • Internal revisions

VK_KHR_external_fence

Name String

VK_KHR_external_fence

Extension Type

Device extension

Registered Extension Number

114

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • Jesse Hall @critsec

Last Modified Date

2017-05-08

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors

An application using external memory may wish to synchronize access to t= hat memory using fences. This extension enables an application to create fences from which non-Vulka= n handles that reference the underlying synchronization primitive can be exported.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR

New Functions

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

This extension borrows concepts, semantics, and language from VK_KHR_external_semaphore. That extension=E2=80=99s issues apply equally to this extension.

VK_KHR_external_fence_capabil= ities

Name String

VK_KHR_external_fence_capabilities

Extension Type

Instance extension

Registered Extension Number

113

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • Jesse Hall @critsec

Last Modified Date

2017-05-08

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors

An application may wish to reference device fences in multiple Vulkan logical devices or instances, in multiple processes, and/or in multiple APIs. This extension provides a set of capability queries and handle definitions that allow an application to determine what types of =E2=80=9Cexternal=E2= =80=9D fence handles an implementation supports for a given set of use cases.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR

  • VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR

  • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR

  • VK_LUID_SIZE_KHR

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

VK_KHR_external_memory

Name String

VK_KHR_external_memory

Extension Type

Device extension

Registered Extension Number

73

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • James Jones @cubanismo

Last Modified Date

2016-10-20

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Jason Ekstrand, Intel

  • Ian Elliot, Google

  • Jesse Hall, Google

  • Tobias Hector, Imagination Technologies

  • James Jones, NVIDIA

  • Jeff Juliano, NVIDIA

  • Matthew Netsch, Qualcomm Technologies, Inc.

  • Daniel Rakos, AMD

  • Carsten Rohde, NVIDIA

  • Ray Smith, ARM

  • Chad Versace, Google

An application may wish to reference device memory in multiple Vulkan logical devices or instances, in multiple processes, and/or in multiple APIs. This extension enables an application to export non-Vulkan handles from Vulkan memory objects such that the underlying resources can be referenced outside the scope of the Vulkan logical device that created them.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR

  • VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR

  • VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR

  • VK_QUEUE_FAMILY_EXTERNAL_KHR

  • VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR

New Enums

None.

New Functions

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

1) How do applications correlate two physical devices across process or Vulkan instance boundaries?

RESOLVED: New device ID fields have been introduced by VK_KHR_external_memory_capabilit= ies. These fields, combined with the existing VkPhysicalDeviceProperties::driverVer= sion field can be used to identify compatible devices across processes, drivers, and APIs. VkPhysicalDeviceProperties::pipelineC= acheUUID is not sufficient for this purpose because despite its description in the specification, it need only identify a unique pipeline cache format in practice. Multiple devices may be able to use the same pipeline cache data, and hence it would be desirable for all of them to have the same pipeline cache UUID. However, only the same concrete physical device can be used when sharing memory, so an actual unique device ID was introduced. Further, the pipeline cache UUID was specific to Vulkan, but correlation with other, non-extensible APIs is required to enable interoperation with those APIs.

2) If memory objects are shared between processes and APIs, is this considered aliasing according to the rules outlined in the Memory Aliasing section?

RESOLVED: Yes. Applications must take care to obey all restrictions imposed on aliased resources when using memory across multiple Vulkan instances or other APIs.=

3) Are new image layouts or metadata required to specify image layouts a= nd layout transitions compatible with non-Vulkan APIs, or with other instances of the same Vulkan driver?

RESOLVED: Separate instances of the same Vulkan driver = running on the same GPU should have identical internal layout semantics, so applications have the tools they need to ensure views of images are consistent between the tw= o instances. Other APIs will fall into two categories: Those that are Vulkan- compatible= , and those that are Vulkan-incompatible. Vulkan-incompatible APIs will require the image to be in the GENERAL layout whenever they are accessing them.

Note this does not attempt to address cross-device transitions, nor transitions to engines on the same device which are not visible within the Vulkan API. Both of these are beyond the scope of this extension.

4) Is a new barrier flag or operation of some type needed to prepare external memory for handoff to another Vulkan instance or API and/or receiv= e it from another instance or API?

RESOLVED: Yes. Some implementations need to perform additional cache management when transitioning memory between address spaces, and other APIs, instances, or processes may operate in a separate address space. Options for defining this transition include:

A new structure has the advantage that the type of external transition c= an be described in as much detail as necessary. However, there is not currently a known need for anything beyond differentiating external vs. internal accesses, so this is likely an over-engineered solution. The access flag bit has the advantage that it can be applied at buffer, image, or global granularity, and semantically it maps pretty well to the operation being described. Additionally, the API already includes VK_ACCESS_MEMORY_READ_BIT and VK_ACCESS_MEMORY_WRITE_BIT which appear to be intended for thi= s purpose. However, there is no obvious pipeline stage that would correspond to an external access, and therefore no clear way to use VK_ACCESS_MEMORY_READ_BIT or VK_ACCESS_MEMORY_WRITE_BIT<= /code>. VkDependencyFlags and VkPipeli= neStageFlags operate at command granularity rather than image or buffer granularity, which would make an entire pipeline barrier an internal=E2=86=92external or external=E2=86=92in= ternal barrier. This may not be a problem in practice, but seems like the wrong scope. Another downside of VkDependencyFlags is that it lac= ks inherent directionality: There are not src and dst variant= s of it in the barrier or dependency description semantics, so two bits might need to be added to describe both internal=E2=86=92external and external=E2=86=92inter= nal transitions. Transitioning a resource to a special queue family corresponds well with th= e operation of transitioning to a separate Vulkan instance, in that both operations ideally include scheduling a barrier on both sides of the transition: Both the releasing and the acquiring queue or process. Using a special queue family requires adding an additional reserved queue family index. Re-using VK_QUEUE_FAMILY_IGNORED would have left it unclear ho= w to transition a concurrent usage resource from one process to another, since the semantics would have likely been equivalent to the currently-ignored transition of VK_QUEUE_FAMILY_IGNORED =E2=86=92 VK_QUEUE_FAM= ILY_IGNORED. Fortunately, creating a new reserved queue family index is not invasive.

Based on the above analysis, the approach of transitioning to a special =E2=80=9Cexternal=E2=80=9D queue family was chosen.

5) Do internal driver memory arrangements and/or other internal driver i= mage properties need to be exported and imported when sharing images across processes or APIs.

RESOLVED: Some vendors claim this is necessary on their= implementations, but it was determined that the security risks of allowing opaque meta data to be passed from applications to the driver were too high. Therefore, implementations which require metadata will need to associate it with the objects represented by the external handles, and rely on the dedicated allocation mechanism to associate the exported and imported memor= y objects with a single image or buffer.

6) Most prior interoperation and cross-process sharing APIs have been ba= sed on image-level sharing. Should Vulkan sharing be based on memory-object sharing or image sharing?

RESOLVED: These extensions have assumed memory-level sh= aring is the correct granularity. Vulkan is a lower-level API than most prior APIs, and as such attempts to closely align with to the underlying primitives of the hardware and system-level drivers it abstracts. In general, the resource that holds the backing store for both images and buffers of various types is memory. Images and buffers are merely metadata containing brief descriptions of the layout of bits within that memory.

Because memory object-based sharing is aligned with the overall Vulkan A= PI design, it exposes the full power of Vulkan on external objects. External memory can be used as backing for sparse images, for example, whereas such usage would be awkward at best with a sharing mechanism based on higher-level primitives such as images. Further, aligning the mechanism with the API in this way provides some hope of trivial compatibility with future API enhancements. If new objects backed by memory objects are added to the API, they too can be used across processes with minimal additions to the base external memory APIs.

Earlier APIs implemented interop at a higher level, and this necessitate= d entirely separate sharing APIs for images and buffers. To co-exist and interoperate with those APIs, the Vulkan external sharing mechanism must accomodate their model. However, if it can be agreed that memory-based sharing is the more desirabl= e and forward-looking design, legacy interoperation considerations can be considered another reason to favor memory-based sharing: While native and legacy driver primitives that may be used to implement sharing may not be a= s low-level as the API here suggests, raw memory is still the least common denominator among the types. Image-based sharing can be cleanly derived from a set of base memory- objec= t sharing APIs with minimal effort, whereas image-based sharing does not generalize well to buffer or raw-memory sharing. Therefore, following the general Vulkan design principle of minimalism, it is better to expose even interopability with image-based native and externa= l primitives via the memory sharing API, and place sufficient limits on their usage to ensure they can be used only as backing for equivalent Vulkan images. This provides a consistent API for applications regardless of which platfor= m or external API they are targeting, which makes development of multi-API an= d multi-platform applications simpler.

7) Should Vulkan define a common external handle type and provide Vulkan functions to facilitate cross-process sharing of such handles rather than relying on native handles to define the external objects?

RESOLVED: No. Cross-process sharing of resources is best left to native platforms. There are myriad security and extensibility issues with such a mechanism, and attempting to re-solve all those issues within Vulkan does not align with Vulkan=E2=80=99s purpose as a graphics API. If desired, such a mechanism could be built as a layer or helper library on top of the opaque native handle defined in this family of extensions.

8) Must implementations provide additional guarantees about state implic= itly included in memory objects for those memory objects that may be exported?

RESOLVED: Implementations must ensure that sharing memo= ry objects does not transfer any information between the exporting and importing instances and APIs other than that required to share the data contained in the memory objects explicitly shared. As specific examples, data from previously freed memory objects that used the same underlying physical memory, and data from memory obects using adjacent physical memory must not be visible to applications importing an exported memory object.

9) Must implementations validate external handles the application provid= es as input to memory import operations?

RESOLVED: Implementations must return an error to the a= pplication if the provided memory handle cannot be used to complete the requested import operation. However, implementations need not validate handles are of the exact type specified by the application.

VK_KHR_external_memory_capab= ilities

Name String

VK_KHR_external_memory_capabilities

Extension Type

Instance extension

Registered Extension Number

72

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • James Jones @cubanismo

Last Modified Date

2016-10-17

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Ian Elliot, Google

  • Jesse Hall, Google

  • James Jones, NVIDIA

An application may wish to reference device memory in multiple Vulkan logical devices or instances, in multiple processes, and/or in multiple APIs. This extension provides a set of capability queries and handle definitions that allow an application to determine what types of =E2=80=9Cexternal=E2= =80=9D memory handles an implementation supports for a given set of use cases.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR

  • VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR

  • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR<= /p>

  • VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR

  • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR

  • VK_LUID_SIZE_KHR

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

1) Why do so many external memory capabilities need to be queried on a per-memory-handle-type basis?

PROPOSED RESOLUTION: This is because some handle types = are based on OS-native objects that have far more limited capabilities than the very generic Vulkan memory objects. Not all memory handle types can name memory objects that support 3D images, for example. Some handle types cannot even support the deferred image and memory binding behavior of Vulkan and require specifying the image when allocating or importing the memory object.

2) Do the VkExternalImageFormatPrope= rtiesKHR and VkExternalBufferPropertiesKHR structs ne= ed to include a list of memory type bits that support the given handle type?

PROPOSED RESOLUTION: No. The memory types that don=E2=80=99t support the handle types will simply be= filtered out of the results returned by vkGetImageMemo= ryRequirements and vkGetBufferMemoryRequirements when a set= of handle types was specified at image or buffer creation time.

3) Should the non-opaque handle types be moved to their own extension?

PROPOSED RESOLUTION: Perhaps. However, defining the handle type bits does very little and does not requir= e any platform-specific types on its own, and it=E2=80=99s easier to maintain= the bitfield values in a single extension for now. Presumably more handle types could be added by separate extensions though, and it would be midly weird to have some platform-specific ones defined in the core spec and some in extensions

4) Do we need a D3D11_TILEPOOL type?

PROPOSED RESOLUTION: No. This is technically possible, but the synchronization is awkward. D3D11 surfaces must be synchronized using shared mutexes, and these synchronization primitives are shared by the entire memory object, so D3D11 shared allocations divided among multiple buffer and image bindings may be difficult to synchronize.

5) Should the Windows 7-compatible handle types be named =E2=80=9CKMT=E2= =80=9D handles or =E2=80=9CGLOBAL_SHARE=E2=80=9D handles?

PROPOSED RESOLUTION: KMT, simply because it is more con= cise.

6) How do applications identify compatible devices and drivers across instance, process, and API boundaries when sharing memory?

PROPOSED RESOLUTION: New device properties are exposed = that allow applications to correctly correlate devices and drivers. A device and driver UUID that must both match to ensure sharing compatibility between two Vulkan instances, or a Vulkan instance and an extensible external API are added. To allow correlating with Direct3D devices, a device LUID is added that corresponds to a DXGI adapter LUID. A driver ID is not needed for Direct3D because mismatched driver component versions are not a currently supported configuration on the Windows OS. Should support for such configurations be introduced at the OS level, further Vulkan extensions would be needed to correlate userspace component builds.

VK_KHR_external_semaphore

Name String

VK_KHR_external_semaphore

Extension Type

Device extension

Registered Extension Number

78

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • James Jones @cubanismo

Last Modified Date

2016-10-21

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jason Ekstrand, Intel

  • Jesse Hall, Google

  • Tobias Hector, Imagination Technologies

  • James Jones, NVIDIA

  • Jeff Juliano, NVIDIA

  • Matthew Netsch, Qualcomm Technologies, Inc.

  • Ray Smith, ARM

  • Chad Versace, Google

An application using external memory may wish to synchronize access to t= hat memory using semaphores. This extension enables an application to create semaphores from which non-Vulkan handles that reference the underlying synchronization primitive can be exported.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR

  • VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR

New Functions

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

1) Should there be restrictions on what side effects can occur when wait= ing on imported semaphores that are in an invalid state?

RESOLVED: Yes. Normally, validating such state would be the responsibility of the application, and the implementation would be free to enter an undefined state if valid usage rules were violated. However, this could cause security concerns when using imported semaphores, as it would require the importing application to trust the exporting application to ensure the state is valid. Requiring this level of trust is undesireable for many potential use cases.=

2) Must implementations validate external handles the application provid= es as input to semaphore state import operations?

RESOLVED: Implementations must return an error to the a= pplication if the provided semaphore state handle cannot be used to complete the requested import operation. However, implementations need not validate handles are of the exact type specified by the application.

VK_KHR_external_semaphore= _capabilities

Name String

VK_KHR_external_semaphore_capabilities

Extension Type

Instance extension

Registered Extension Number

77

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • James Jones @cubanismo

Last Modified Date

2016-10-20

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jesse Hall, Google

  • James Jones, NVIDIA

  • Jeff Juliano, NVIDIA

An application may wish to reference device semaphores in multiple Vulka= n logical devices or instances, in multiple processes, and/or in multiple APIs. This extension provides a set of capability queries and handle definitions that allow an application to determine what types of =E2=80=9Cexternal=E2= =80=9D semaphore handles an implementation supports for a given set of use cases.

New Object Types

None.

New Enum Constants

  • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR

  • VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR

  • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR

  • VK_LUID_SIZE_KHR

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

VK_KHR_get_memory_requirements2<= /h4>
Name String

VK_KHR_get_memory_requirements2

Extension Type

Device extension

Registered Extension Number

147

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Jason Ekstrand @jekstrand

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jason Ekstrand, Intel

  • Jeff Bolz, NVIDIA

  • Jesse Hall, Google

This extension provides new entry points to query memory requirements of images and buffers in a way that can be easily extended by other extensions= , without introducing any further entry points. The Vulkan 1.0 VkMemoryRequirements and VkSparseImageMemoryRequirements struct= ures do not include a sType/pNext, this extension wraps them in new str= uctures with sType/pNext so an application can query a chain o= f memory requirements structures by constructing the chain and letting the implementation fill them in. A new command is added for each vkGet*MemoryRequrements comman= d in core Vulkan 1.0.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR

    • VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR

    • VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR

    • VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR

    • VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR

New Enums

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

Version History

  • Revision 1, 2017-03-23 (Jason Ekstrand)

    • Internal revisions

VK_KHR_get_physical_devic= e_properties2

Name String

VK_KHR_get_physical_device_properties2

Extension Type

Instance extension

Registered Extension Number

60

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jeff Bolz, NVIDIA

  • Ian Elliott, Google

This extension provides new entry points to query device features, devic= e properties, and format properties in a way that can be easily extended by other extensions, without introducing any further entry points. The Vulkan 1.0 feature/limit/formatproperty structures do not include sType/pNext members. This extension wraps them in new structures with sType/p= Next members, so an application can query a chain of feature/limit/formatpropert= y structures by constructing the chain and letting the implementation fill them in. A new command is added for each vkGetPhysicalDevice* command i= n core Vulkan 1.0. The new feature structure (and a chain of extension structures) can also be passed in to device creation to enable features.

This extension also allows applications to use the physical-device components of device extensions before vkCreateDevice i= s called.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR

    • VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR

New Enums

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

Examples

    // Get features with a hypothetical future extension.
    VkHypotheticalExtensionFeaturesKHR hypotheticalFeatures =3D
    {
        VK_STRUCTURE_TYPE_HYPOTHETICAL_FEATURES_KHR,                       =
     // sType
        NULL,                   =
                                                // =
pNext
    };

    VkPhysicalDeviceFeatures2KHR features =3D
    {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR,                  =
     // sType
        &hypotheticalFeatures,                                         =
         // pNext
    };

    // After this call, features and hypotheticalFe=
atures have been filled out.
    vkGetPhysicalDeviceFeatures2KHR(physicalDevice, &features);

    // Properties/limits can be chained and queried=
 similarly.

    // Enable some features:
    VkHypotheticalExtensionFeaturesKHR enabledHypotheticalFeatures =3D
    {
        VK_STRUCTURE_TYPE_HYPOTHETICAL_FEATURES_KHR,                       =
     // sType
        NULL,                   =
                                                // =
pNext
    };

    VkPhysicalDeviceFeatures2KHR enabledFeatures =3D
    {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR,                  =
     // sType
        &enabledHypotheticalFeatures,                                  =
         // pNext
    };

    enabledFeatures.features.xyz =3D VK_TRUE;
    enabledHypotheticalFeatures.abc =3D VK_TRUE;

    VkDeviceCreateInfo deviceCreateInfo =3D
    {
        VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                              =
     // sType
        &enabledFeatures,                                              =
         // pNext
        ...
        NULL,                   =
                                                // =
pEnabledFeatures
    }

    VkDevice device;
    vkCreateDevice(physicalDevice, &deviceCreateInfo, NULL, &device);

Version History

  • Revision 1, 2016-09-12 (Jeff Bolz)

    • Internal revisions

  • Revision 2, 2016-11-02 (Ian Elliott)

    • Added ability for applications to use the physical-device components of device extensions before vkCreateDevice is called.

VK_KHR_maintenance1

Name String

VK_KHR_maintenance1

Extension Type

Device extension

Registered Extension Number

70

Revision

2

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Piers Daniell @pdaniell-nv

Last Modified Date

2018-03-13

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Dan Ginsburg, Valve

  • Daniel Koch, NVIDIA

  • Daniel Rakos, AMD

  • Jan-Harald Fredriksen, ARM

  • Jason Ekstrand, Intel

  • Jeff Bolz, NVIDIA

  • Jesse Hall, Google

  • John Kessenich, Google

  • Michael Worcester, Imagination Technologies

  • Neil Henning, Codeplay Software Ltd.

  • Piers Daniell, NVIDIA

  • Slawomir Grajewski, Intel

  • Tobias Hector, Imagination Technologies

  • Tom Olson, ARM

VK_KHR_maintenance1 adds a collection of minor features tha= t were intentionally left out or overlooked from the original Vulkan 1.0 release.<= /p>

The new features are as follows:

  • Allow 2D and 2D array image views to be created from 3D images, which can then be used as color framebuffer attachments. This allows applications to render to slices of a 3D image.

  • Support vkCmdCopyImage between 2D array layers and 3= D slices. This extension allows copying from layers of a 2D array image to slices of a 3D image and vice versa.

  • Allow negative height to be specified in the VkViewport::height field to perform y-inversio= n of the clip-space to framebuffer-space transform. This allows apps to avoid having to use gl_Position.y =3D -gl_Positio= n.y in shaders also targeting other APIs.

  • Allow implementations to express support for doing just transfers and clears of image formats that they otherwise support no other format features for. This is done by adding new format feature flags VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR and VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR.

  • Support vkCmdFillBuffer on transfer-only queues. Previously vkCmdFillBuffer was defined to only work on= command buffers allocated from command pools which support graphics or compute queues. It is now allowed on queues that just support transfer operations.

  • Fix the inconsistency of how error conditions are returned between the vkCreateGraphicsPipelines and vkCreateComputePipelines functions and the vkAllocateDescriptorSets an= d vkAllocateCommandBuffers functions.

  • Add new VK_ERROR_OUT_OF_POOL_MEMORY_KHR error so implementa= tions can give a more precise reason for vkAllocateDesc= riptorSets failures.

  • Add a new command vkTrimCommandPoolKHR which g= ives the implementation an opportunity to release any unused command pool memory back to the system.

New Object Types

None.

New Enum Constants

  • VK_ERROR_OUT_OF_POOL_MEMORY_KHR

  • VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR

  • VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR

  • VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR

New Enums

None.

New Structures

None.

New Functions

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

  1. Are viewports with zero height allowed?

    RESOLVED: Yes, although they have low utility.

Version History

  • Revision 1, 2016-10-26 (Piers Daniell)

    • Internal revisions

  • Revision 2, 2018-03-13 (Jon Leech)

    • Add issue for zero-height viewports

VK_KHR_maintenance2

Name String

VK_KHR_maintenance2

Extension Type

Device extension

Registered Extension Number

118

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Michael Worcester @michaelworcester

Last Modified Date

2017-09-05

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Michael Worcester, Imagination Technologies

  • Stuart Smith, Imagination Technologies

  • Jeff Bolz, NVIDIA

  • Daniel Koch, NVIDIA

  • Jan-Harald Fredriksen, ARM

  • Daniel Rakos, AMD

  • Neil Henning, Codeplay

  • Piers Daniell, NVIDIA

VK_KHR_maintenance2 adds a collection of minor features tha= t were intentionally left out or overlooked from the original Vulkan 1.0 release.<= /p>

The new features are as follows:

  • Allow the application to specify which aspect of an input attachment might be read for a given subpass.

  • Allow implementations to express the clipping behavior of points.

  • Allow creating images with usage flags that may not be supported for the base image=E2=80=99s format, but are supported for image views of the image= that have a different but compatible format.

  • Allow creating uncompressed image views of compressed images.

  • Allow the application to select between an upper-left and lower-left origin for the tessellation domain space.

  • Adds two new image layouts for depth stencil images to allow either the depth or stencil aspect to be read-only while the other aspect is writable.

Input Attachment Specification

Input attachment specification allows an application to specify which as= pect of a multi-aspect image (e.g. a combined depth stencil format) will be accessed via a subpassLoad operation.

On some implementations there may be a= performance penalty if the implementation does not know (at vkCreateRenderPass= time) which aspect(s) of multi-aspect images can be b= e accessed as input attachments.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_= KHR

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR

    • VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR

    • VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE= _INFO_KHR

  • Extending VkImageCreateFlagBits:

    • VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR

    • VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR

  • Extending VkImageLayout

    • VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR

    • VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR

  • VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR

  • VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR

New Functions

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Input Attachment Specifi= cation Example

Consider the case where a render pass has two subpasses and two attachme= nts.

Attachment 0 has the format VK_FORMAT_D24_UNORM_S8_UINT, at= tachment 1 has some color format.

Subpass 0 writes to attachment 0, subpass 1 reads only the depth informa= tion from attachment 0 (using inputAttachmentRead) and writes to attachment 1.

    VkInputAttachm=
entAspectReferenceKHR references[] =3D {
        {
            .subpass =3D 1,
            .inputAttachmentIndex =3D 0,
            .aspectMask =3D VK_IMAGE_ASPECT_DEPTH_BIT
        }
    };

    VkRenderPassInputAttachmentAspectCreateInfoKHR specifyAspects =3D {
        .sType =3D VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CR=
EATE_INFO_KHR,
        .pNext =3D NULL,
        .aspectReferenceCount =3D 1,
        .pAspectReferences =3D references
    };


    VkRenderPassCreateInfo createInfo =3D {
        ...
        .pNext =3D &specifyAspects,
        ...
    }

    vkCreateRenderPass(...);

Issues

1) What is the default tessellation domain origin?

RESOLVED: Vulkan 1.0 originally inadvertently documente= d a lower-left origin, but the conformance tests and all implementations implemented an upper-left origin. This extension adds a control to select between lower-left (for compatibility with OpenGL) and upper-left, and we retroactively fix unextended Vulkan to have a default of an upper-left origin.

Version History

  • Revision 1, 2017-04-28

VK_KHR_maintenance3

Name String

VK_KHR_maintenance3

Extension Type

Device extension

Registered Extension Number

169

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • Jeff Bolz @jeffbolznv

Status

Draft

Last Modified Date

2017-09-05

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • Jeff Bolz, NVIDIA

VK_KHR_maintenance3 adds a collection of minor features tha= t were intentionally left out or overlooked from the original Vulkan 1.0 release.<= /p>

The new features are as follows:

  • A limit on the maximum number of descriptors that are supported in a single descriptor set layout. Some implementations have a limit on the total size of descriptors in a set, which can=E2=80=99t be expressed in terms of the limits in Vulkan 1.0.=

  • A limit on the maximum size of a single memory allocation. Some platforms have kernel interfaces that limit the maximum size of an allocation.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR

    • VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR

New Enums

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

Version History

  • Revision 1, 2017-08-22

VK_KHR_multiview

This extension has the same goal as the OpenGL ES GL_OVR_multiview extension - it enables rendering to multiple =E2=80=9Cviews=E2=80=9D by rec= ording a single set of commands to be executed with slightly different behavior for each view. It includes a concise way to declare a render pass with multiple views, and gives implementations freedom to render the views in the most efficient way possible.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR<= /p>

  • Extending VkDependencyFlagBits

    • VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR

New Enums

None.

New Functions

None.

New SPIR-V Capabilities

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Issues

None.

Examples

None.

Version History

  • Revision 1, 2016-10-28 (Jeff Bolz)

    • Internal revisions

VK_KHR_relaxed_block_layout

Name String

VK_KHR_relaxed_block_layout

Extension Type

Device extension

Registered Extension Number

145

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • John Kessenich @johnkslang

Last Modified Date

2017-03-26

IP Status

No known IP claims.

Interactions and External Dependencies
  • Promoted to Vulkan 1.1 Core

Contributors
  • John Kessenich, Google

The VK_KHR_relaxed_block_layout extension allows implementa= tions to indicate they can support more variation in block Offset decor= ations. For example, placing a vector of three floats at an offset of 16*N + 4.

See Offset and Stride Assignment for details.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Version History

  • Revision 1, 2017-03-26 (JohnK)

VK_KHR_sampler_ycbcr_conversion<= /h4>
Name String

VK_KHR_sampler_ycbcr_conversion

Extension Type

Device extension

Registered Extension Number

157

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • Andrew Garrard @fluppeteer

Last Modified Date

2017-08-11

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Andrew Garrard, Samsung Electronics

  • Tobias Hector, Imagination Technologies

  • James Jones, NVIDIA

  • Daniel Koch, NVIDIA

  • Daniel Rakos, AMD

  • Romain Guy, Google

  • Jesse Hall, Google

  • Tom Cooksey, ARM Ltd

  • Jeff Leger, Qualcomm Technologies, Inc

  • Jan-Harald Fredriksen, ARM Ltd

  • Jan Outters, Samsung Electronics

  • Alon Or-bach, Samsung Electronics

  • Michael Worcester, Imagination Technologies

  • Jeff Bolz, NVIDIA

  • Tony Zlatinski, NVIDIA

  • Matthew Netsch, Qualcomm Technologies, Inc

This extension provides the ability to perform specified color space conversions during texture sampling operations. It also adds a selection of multi-planar formats, including the ability to bind memory to the planes of an image collectively or separately.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR<= /p>

    • VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR

    • VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR

    • VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR<= /p>

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURE= S_KHR

  • Extending VkFormat:

    • VK_FORMAT_G8B8G8R8_422_UNORM_KHR

    • VK_FORMAT_B8G8R8G8_422_UNORM_KHR

    • VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR

    • VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR

    • VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR

    • VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR

    • VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR

    • VK_FORMAT_R10X6_UNORM_PACK16_KHR

    • VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR

    • VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR

    • VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR

    • VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR

    • VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR

    • VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR

    • VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR

    • VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR

    • VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR

    • VK_FORMAT_R12X4_UNORM_PACK16_KHR

    • VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR

    • VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR

    • VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR

    • VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR

    • VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR

    • VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR

    • VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR

    • VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR

    • VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR

    • VK_FORMAT_G16B16G16R16_422_UNORM_KHR

    • VK_FORMAT_B16G16R16G16_422_UNORM_KHR

    • VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR

    • VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR

    • VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR

    • VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR

    • VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR

  • Extending VkImageAspectFlagBits:

    • VK_IMAGE_ASPECT_PLANE_0_BIT_KHR

    • VK_IMAGE_ASPECT_PLANE_1_BIT_KHR

    • VK_IMAGE_ASPECT_PLANE_2_BIT_KHR

  • Extending VkImageCreateFlagBits:

    • VK_IMAGE_CREATE_DISJOINT_BIT_KHR

  • Extending VkFormatFeatureFlagBits:

    • VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR

    • VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT= _KHR

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTR= UCTION_FILTER_BIT_KHR

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUC= TION_EXPLICIT_BIT_KHR

    • VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUC= TION_EXPLICIT_FORCEABLE_BIT_KHR

    • VK_FORMAT_FEATURE_DISJOINT_BIT_KHR

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted. The original type, enum and command names are still available as aliases of the core functionality.

Version History

  • Revision 1, 2017-01-24 (Andrew Garrard)

    • Initial draft

  • Revision 2, 2017-01-25 (Andrew Garrard)

    • After initial feedback

  • Revision 3, 2017-01-27 (Andrew Garrard)

    • Higher bit depth formats, renaming, swizzle

  • Revision 4, 2017-02-22 (Andrew Garrard)

    • Added query function, formats as RGB, clarifications

  • Revision 5, 2017-04 (Andrew Garrard)

    • Simplified query and removed output conversions

  • Version 6, 2017-4-24 (Andrew Garrard)

    • Tidying, incorporated new image query, restored transfer functions

  • Version 7, 2017-04-25 (Andrew Garrard)

    • Added cosited option/midpoint requirement for formats, "bypassConversion"

  • Version 8, 2017-04-25 (Andrew Garrard)

    • Simplified further

  • Version 9, 2017-04-27 (Andrew Garrard)

    • Disjoint no more

  • Version 10, 2017-04-28 (Andrew Garrard)

    • Restored disjoint

  • Version 11, 2017-04-29 (Andrew Garrard)

    • Now Ycbcr conversion, and KHR

  • Version 12, 2017-06-06 (Andrew Garrard)

    • Added conversion to image view creation

  • Version 13, 2017-07-13 (Andrew Garrard)

    • Allowed cosited-only chroma samples for formats

  • Version 14, 2017-08-11 (Andrew Garrard)

    • Reflected quantization changes in BT.2100-1

VK_KHR_shader_draw_parameters

Name String

VK_KHR_shader_draw_parameters

Extension Type

Device extension

Registered Extension Number

64

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Daniel Koch @dgkoch

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Daniel Koch, NVIDIA Corporation

  • Jeff Bolz, NVIDIA

  • Daniel Rakos, AMD

  • Jan-Harald Fredriksen, ARM

  • John Kessenich, Google

  • Stuart Smith, IMG

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_KHR_shader_draw_parameters

The extension provides access to three additional built-in shader variab= les in Vulkan:

  • BaseInstance, which contains the firstInstance= parameter passed to draw commands,

  • BaseVertex, which contains the firstVertex/vertexOffset parameter passed to draw commands, and

  • DrawIndex, which contains the index of the draw call curren= tly being processed from an indirect draw call.

When using GLSL source-based shader languages, the following variables f= rom GL_ARB_shader_draw_parameters can map to these SPIR-V built-in decorations:

  • in int gl_BaseInstanceARB; =E2=86=92 BaseInstance,

  • in int gl_BaseVertexARB; =E2=86=92 BaseVertex,= and

  • in int gl_DrawIDARB; =E2=86=92 DrawIndex.

New Object Types

None.

New Enum Constants

None.

New Enums

None.

New Structures

None.

New Functions

None.

New Built-In Variables

New SPIR-V Capabilities

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, howe= ver a feature bit was added to distinguish whether it=E2=80=99s actually available or not.

Issues

1) Is this the same functionality as GL_ARB_shader_draw_parameters?

RESOLVED: It=E2=80=99s actually a superset as it also a= dds in support for arrayed drawing commands.

In GL for GL_ARB_shader_draw_parameters, gl_BaseVertexARB h= olds the integer value passed to the parameter to the command that resulted in the current shader invocation. In the case where the command has no baseVertex parameter, the= value of gl_BaseVertexARB is zero. This means that gl_BaseVertexARB =3D baseVertex (= for glDrawElements commands with baseVertex) or 0. In particular there are no glDrawArrays commands that take a baseVertex parameter.

Now in Vulkan, we have BaseVertex =3D vertexOffset (for indexed drawing commands) or firstVertex (for arrayed drawing commands= ), and so Vulkan=E2=80=99s version is really a superset of GL functionality.

Version History

  • Revision 1, 2016-10-05 (Daniel Koch)

    • Internal revisions

VK_KHR_storage_buffer_storag= e_class

Name String

VK_KHR_storage_buffer_storage_class

Extension Type

Device extension

Registered Extension Number

132

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Alexander Galazin @alegal-arm

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • Alexander Galazin, ARM

  • David Neto, Google

This extension adds support for the following SPIR-V extension in Vulkan= :

  • SPV_KHR_storage_buffer_storage_class

This extension provides a new SPIR-V StorageBuffer storage = class. A Block-decorated object in this class is equivalent to a BufferBlock-decorated object in the Uniform stora= ge class.

New Enum Constants

None.

New Structures

None.

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1.

Issues

None.

Version History

  • Revision 1, 2017-03-23 (Alexander Galazin)

    • Initial draft

VK_KHR_variable_pointers

Name String

VK_KHR_variable_pointers

Extension Type

Device extension

Registered Extension Number

121

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • Jesse Hall @critsec

Last Modified Date

2017-09-05

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • John Kessenich, Google

  • Neil Henning, Codeplay

  • David Neto, Google

  • Daniel Koch, Nvidia

  • Graeme Leese, Broadcom

  • Weifeng Zhang, Qualcomm

  • Stephen Clarke, Imagination Technologies

  • Jason Ekstrand, Intel

  • Jesse Hall, Google

The VK_KHR_variable_pointers extension allows implementatio= ns to indicate their level of support for the SPV_KHR_variable_pointers SPIR-V extension. The SPIR-V extension allows shader modules to use invocation-private pointers into uniform and/or storage buffers, where the pointer values can be dynamic and non-uniform.

The SPV_KHR_variable_pointers extension introduces two capabilities. The first, VariablePointersStorageBuffer, must be supported by all implementations of this extension. The second, VariablePointers, is optional.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR

Promotion to Vulkan 1.1

All functionality in this extension is included in core Vulkan 1.1, with= the KHR suffix omitted, however support for the variablePointersStor= ageBuffer feature is made optional. The original type, enum and command names are still available as aliases of the core functionality.

Issues

1) Do we need an optional property for the SPIR-V VariablePointersStorageBuffer capability or should it be manda= tory when this extension is advertised?

RESOLVED: Add it as a distinct feature, but make suppor= t mandatory. Adding it as a feature makes the extension easier to include in a future core API version. In the extension, the feature is mandatory, so that presence of the extension guarantees some functionality. When included in a core API version, the feature would be optional.

2) Can support for these capabilities vary between shader stages?

RESOLVED: No, if the capability is supported in any sta= ge it must be supported in all stages.

3) Should the capabilities be features or limits?

RESOLVED: Features, primarily for consistency with othe= r similar extensions.

Version History

  • Revision 1, 2017-03-14 (Jesse Hall and John Kessenich)

    • Internal revisions

VK_EXT_debug_marker

Name String

VK_EXT_debug_marker

Extension Type

Device extension

Registered Extension Number

23

Revision

4

Extension and Version Dependencies
Deprecation state
Contact
  • Baldur Karlsson @baldurk

Last Modified Date

2017-01-31

IP Status

No known IP claims.

Contributors
  • Baldur Karlsson

  • Dan Ginsburg, Valve

  • Jon Ashburn, LunarG

  • Kyle Spagnoli, NVIDIA

The VK_EXT_debug_marker extension is a device extension. It introduces concepts of object naming and tagging, for better tracking of Vulkan objects, as well as additional commands for recording annotations of named sections of a workload to aid organization and offline analysis in external tools.

New Object Types

None

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT

    • VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT

    • VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT

New Enums

None

Examples

Example 1

Associate a name with an image, for easier debugging in external tools o= r with validation layers that can print a friendly name when referring to objects in error messages.

    extern VkDevice device;
    extern VkImage image;

    // Must call extension functions through a func=
tion pointer:
    PFN_vkDebugMarkerSetObjectNameEXT pfnDebugMarkerSetObjectNameEXT =3D (P=
FN_vkDebugMarkerSetObjectNameEXT)vkGetDeviceProcAddr(device, "vkDebugM=
arkerSetObjectNameEXT");

    // Set a name on the image
    const VkDebugMarkerObjectNameInfoEXT i=
mageNameInfo =3D
    {
        VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT, // sType
        NULL,                   =
                        // pNext
        VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,          // objectType
        (uint64_t)image,                                // object
        "Brick Diffuse Texture",                        // pObjectName
    };

    pfnDebugMarkerSetObjectNameEXT(device, &imageNameInfo);

    // A subsequent error might print:
    //   Image 'Brick Diffuse Texture' (0xc0dec0ded=
eadbeef) is used in a
    //   command buffer with no memory bound to it.=

Example 2

Annotating regions of a workload with naming information so that offline analysis tools can display a more usable visualisation of the commands submitted.

    extern VkDevice device;
    extern VkCommandBuffer commandBuffer;

    // Must call extension functions through a func=
tion pointer:
    PFN_vkCmdDebugMarkerBeginEXT pfnCmdDebugMarkerBeginEXT =3D (PFN_vkCmdDe=
bugMarkerBeginEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerBeginEX=
T");
    PFN_vkCmdDebugMarkerEndEXT pfnCmdDebugMarkerEndEXT =3D (PFN_vkCmdDebugM=
arkerEndEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerEndEXT");
    PFN_vkCmdDebugMarkerInsertEXT pfnCmdDebugMarkerInsertEXT =3D (PFN_vkCmd=
DebugMarkerInsertEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerInse=
rtEXT");

    // Describe the area being rendered
    const VkDebugMarkerMarkerInfoEXT house=
Marker =3D
    {
        VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT, // sType
        NULL,                   =
                        // pNext
        "Brick House", =
                                 // pMarkerName
        { 1.0f, <=
span class=3D"float">0.0f, 0.0f, =
1.0f },                     // color
    };

    // Start an annotated group of calls under the =
'Brick House' name
    pfnCmdDebugMarkerBeginEXT(commandBuffer, &houseMarker);
    {
        // A mutable structure for each part being =
rendered
        VkDebugMarkerMarkerInfoEXT housePartMarker =3D
        {
            VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT, // sType
            NULL,               =
                            // pNext
            NULL,               =
                            // pMarkerName
            { 0.0f, 0.0f, 0.0f, 0.0f },                     // color
        };

        // Set the name and insert the marker
        housePartMarker.pMarkerName =3D "Walls";
        pfnCmdDebugMarkerInsertEXT(commandBuffer, &housePartMarker);

        // Insert the drawcall for the walls
        vkCmdDrawIndexed(commandBuffer, 1000=
, 1, 0, 0, 0);

        // Insert a recursive region for two sets o=
f windows
        housePartMarker.pMarkerName =3D "Windows";
        pfnCmdDebugMarkerBeginEXT(commandBuffer, &housePartMarker);
        {
            vkCmdDrawIndexed(commandBuffer, 75, 6, 1000, =
0, 0);
            vkCmdDrawIndexed(commandBuffer, 100, 2, 1450,=
 0, 0);
        }
        pfnCmdDebugMarkerEndEXT(commandBuffer);

        housePartMarker.pMarkerName =3D "Front Door";
        pfnCmdDebugMarkerInsertEXT(commandBuffer, &housePartMarker);

        vkCmdDrawIndexed(commandBuffer, 350,=
 1, 1650, 0, 0);

        housePartMarker.pMarkerName =3D "Roof";
        pfnCmdDebugMarkerInsertEXT(commandBuffer, &housePartMarker);

        vkCmdDrawIndexed(commandBuffer, 500,=
 1, 2000, 0, 0);
    }
    // End the house annotation started above
    pfnCmdDebugMarkerEndEXT(commandBuffer);

Issues

1) Should the tag or name for an object be specified using the pNe= xt parameter in the object=E2=80=99s Vk*CreateInfo structure?

RESOLVED: No. While this fits with other Vulkan patterns and would allow more type safety and future proofing against future objects, it has notable downsides. In particular passing the name at Vk*CreateInfo time does not = allow renaming, prevents late binding of naming information, and does not allow naming of implicitly created objects such as queues and swapchain images.

2) Should the command annotation functions vkC= mdDebugMarkerBeginEXT and vkCmdDebugMarkerEndEXT support the ability = to specify a color?

RESOLVED: Yes. The functions have been expanded to take an optional color which can be use= d at will by implementations consuming the command buffer annotations in thei= r visualisation.

3) Should the functions added in this extension accept an extensible structure as their parameter for a more flexible API, as opposed to direct function parameters? If so, which functions?

RESOLVED: Yes. All functions have been modified to take a structure type with extensible pNext pointer, to allow future extensions to add additional an= notation information in the same commands.

Version History

  • Revision 1, 2016-02-24 (Baldur Karlsson)

    • Initial draft, based on LunarG marker spec

  • Revision 2, 2016-02-26 (Baldur Karlsson)

    • Renamed Dbg to DebugMarker in function names

    • Allow markers in secondary command buffers under certain circumstances

    • Minor language tweaks and edits

  • Revision 3, 2016-04-23 (Baldur Karlsson)

    • Reorganise spec layout to closer match desired organisation

    • Added optional color to markers (both regions and inserted labels)

    • Changed functions to take extensible structs instead of direct function parameters

  • Revision 4, 2017-01-31 (Baldur Karlsson)

    • Added explicit dependency on VK_EXT_debug_report

    • Moved definition of VkDebugReportObjectTypeE= XT to debug report chapter.

    • Fixed typo in dates in revision history

VK_EXT_debug_report

Name String

VK_EXT_debug_report

Extension Type

Instance extension

Registered Extension Number

12

Revision

9

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Courtney Goeltzenleuchter @courtney-g

Last Modified Date

2017-09-12

IP Status

No known IP claims.

Contributors
  • Courtney Goeltzenleuchter, LunarG

  • Dan Ginsburg, Valve

  • Jon Ashburn, LunarG

  • Mark Lobodzinski, LunarG

Due to the nature of the Vulkan interface, there is very little error information available to the developer and application. By enabling optional validation layers and using the VK_EXT_debug_rep= ort extension, developers can obtain much mor= e detailed feedback on the application=E2=80=99s use of Vulkan. This extension defines a way for layers and the implementation to call back to the application for events of interest to the application.

New Object Types

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT

  • Extending VkResult:

    • VK_ERROR_VALIDATION_FAILED_EXT

New Function Pointers

Examples

VK_EXT_debug_report allows an application to register multi= ple callbacks with the validation layers. Some callbacks may log the information to a file, others may cause a debug break point or other application defined behavior. An application can register callbacks eve= n when no validation layers are enabled, but they will only be called for loader and, if implemented, drive= r events.

To capture events that occur while creating or destroying an instance an application can link a VkDebugReportCallbackCreateInfoEXT structure to the pNext element of the VkInstanceCr= eateInfo structure given to vkCreateInstance. This callback is only valid for the duration of the vkCre= ateInstance and the vkDestroyInstance call. Use vkCreateDebugReportCallbackEXT to c= reate persistent callback objects.

Example uses: Create three callback objects. One will log errors and warnings to the debug console using Windows OutputDebugString. The second will cause the debugger to break at that callback when an error happens and the third will log warnings to stdout.

    VkResult res;
    VkDebugReportCallbackEXT cb1, cb2, cb3;

    VkDebugReportCallbackCreateInfoEXT callback1 =3D {
            VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,    // sType
            NULL,               =
                                        // pNext
            VK_DEBUG_REPORT_ERROR_BIT_EXT |                             // flags
            VK_DEBUG_REPORT_WARNING_BIT_EXT,
            myOutputDebugString,                                        // pfnCallback
            NULL                =
                                        // pUserDat=
a
    };
    res =3D vkCreateDebugReportCallbackEXT(instance, &callback1, &c=
b1);
    if (res !=3D VK_SUCCESS)
       /* Do error handling for VK_ERROR_OUT_OF_MEM=
ORY */

    callback.flags =3D VK_DEBUG_REPORT_ERROR_BIT_EXT;
    callback.pfnCallback =3D myDebugBreak;
    callback.pUserData =3D NULL;
    res =3D vkCreateDebugReportCallbackEXT(instance, &callback, &cb=
2);
    if (res !=3D VK_SUCCESS)
       /* Do error handling for VK_ERROR_OUT_OF_MEM=
ORY */

    VkDebugReportCallbackCreateInfoEXT callback3 =3D {
            VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,    // sType
            NULL,               =
                                        // pNext
            VK_DEBUG_REPORT_WARNING_BIT_EXT,                            // flags
            mystdOutLogger,                                             // pfnCallback
            NULL                =
                                        // pUserDat=
a
    };
    res =3D vkCreateDebugReportCallbackEXT(instance, &callback3, &c=
b3);
    if (res !=3D VK_SUCCESS)
       /* Do error handling for VK_ERROR_OUT_OF_MEM=
ORY */

    ...

    /* remove callbacks when cleaning up */
    vkDestroyDebugReportCallbackEXT(instance, cb1);
    vkDestroyDebugReportCallbackEXT(instance, cb2);
    vkDestroyDebugReportCallbackEXT(instance, cb3);
Note

In the initial release of the VK_EXT_debug_report extension= , the token VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT was used. Starting in version 2 of the extension branch, VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT is use= d instead for consistency with Vulkan naming rules. The older enum is still available for backwards compatibility.

Note

In the initial release of the VK_EXT_debug_report extension= , the token VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT was used. Starting in version 8 of the extension branch, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT is u= sed instead for consistency with Vulkan naming rules. The older enum is still available for backwards compatibility.

Issues

1) What is the hierarchy / seriousness of the message flags? E.g. ERROR > WARN > PERF_WARN =E2= =80=A6=E2=80=8B

RESOLVED: There is no specific hierarchy. Each bit is independent and should be checked via bitwise AND. For example:

    if (localFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
        process error message
    }
    if (localFlags & VK_DEBUG_REPORT_DEB=
UG_BIT_EXT) {
        process debug message
    }

The validation layers do use them in a hierarchical way (ERROR > WARN > PERF, WARN > DEBU= G > INFO) and they (at least at the time of this writing) only set one bit at a time. But it is not a requirement of this extension.

It is possible that a layer may intercept and change, or augment the fla= gs with extension values the application=E2=80=99s debug report handler may no= t be familiar with, so it is important to treat each flag independently.

2) Should there be a VU requiring VkDebugReportCallbackCreateInfoEXT:= :flags to be non-zero?

RESOLVED: It may not be very useful, but we do not need= VU statement requiring the VkDebugReportCallbackCreateInfoEXT::msgFla= gs at create-time to be non-zero. One can imagine that apps may prefer it as it allows them to set the mask a= s desired - including nothing - at runtime without having to check.

3) What is the difference between VK_DEBUG_REPORT_DEBUG_BIT_EXT and VK_DEBUG_REPORT_INFORMATION_BIT_EXT?

RESOLVED: VK_DEBUG_REPORT_DEBUG_BIT_EXT sp= ecifies information that could be useful debugging the Vulkan implementation itself.

Version History

  • Revision 1, 2015-05-20 (Courtney Goetzenleuchter)

    • Initial draft, based on LunarG KHR spec, other KHR specs

  • Revision 2, 2016-02-16 (Courtney Goetzenleuchter)

    • Update usage, documentation

  • Revision 3, 2016-06-14 (Courtney Goetzenleuchter)

    • Update VK_EXT_DEBUG_REPORT_SPEC_VERSION to indicate added support for vkCreateInstance and vkDestroyInstance

  • Revision 4, 2016-12-08 (Mark Lobodzinski)

    • Added Display_KHR, DisplayModeKHR extension objects

    • Added ObjectTable_NVX, IndirectCommandsLayout_NVX extension objects

    • Bumped spec revision

    • Retroactively added version history

  • Revision 5, 2017-01-31 (Baldur Karlsson)

  • Revision 6, 2017-01-31 (Baldur Karlsson)

    • Added VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT

  • Revision 7, 2017-04-20 (Courtney Goeltzenleuchter)

    • Clarify wording and address questions from developers.

  • Revision 8, 2017-04-21 (Courtney Goeltzenleuchter)

    • Remove unused enum VkDebugReportErrorEXT

  • Revision 9, 2017-09-12 (Tobias Hector)

    • Added interactions with Vulkan 1.1

VK_AMD_draw_indirect_count

Name String

VK_AMD_draw_indirect_count

Extension Type

Device extension

Registered Extension Number

34

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Daniel Rakos @drakos-amd

Last Modified Date

2016-08-23

IP Status

No known IP claims.

Contributors
  • Matthaeus G. Chajdas, AMD

  • Derrick Owens, AMD

  • Graham Sellers, AMD

  • Daniel Rakos, AMD

  • Dominik Witczak, AMD

This extension allows an application to source the number of draw calls = for indirect draw calls from a buffer. This enables applications to generate arbitrary amounts of draw commands an= d execute them without host intervention.

Version History

  • Revision 2, 2016-08-23 (Dominik Witczak)

    • Minor fixes

  • Revision 1, 2016-07-21 (Matthaeus Chajdas)

    • Initial draft

VK_AMD_negative_viewport_height<= /h4>
Name String

VK_AMD_negative_viewport_height

Extension Type

Device extension

Registered Extension Number

36

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Matthaeus G. Chajdas @anteru

Last Modified Date

2016-09-02

IP Status

No known IP claims.

Contributors
  • Matthaeus G. Chajdas, AMD

  • Graham Sellers, AMD

  • Baldur Karlsson

Interactions and External Dependencies
  • Obsoleted by VK_KHR_maintenance1

  • Obsoleted by Vulkan 1.1

This extension allows an application to specify a negative viewport heig= ht. The result is that the viewport transformation will flip along the y-axis.<= /p>

  • Allow negative height to be specified in the VkViewport::height field to perform y-inversio= n of the clip-space to framebuffer-space transform. This allows apps to avoid having to use gl_Position.y =3D -gl_Positio= n.y in shaders also targeting other APIs.

Obsoletion by = VK_KHR_maintenance1 and Vulkan 1.1

Functionality in this extension is included in VK_KHR_maintenance1= and Vulkan 1.1. Due to some slight behavioral differences, this extension must not be enabled alongside VK_KHR_maintenance1, or in an instance creat= ed with version 1.1 or later requested in VkApplicationInfo:= :apiVersion.

Version History

  • Revision 1, 2016-09-02 (Matthaeus Chajdas)

    • Initial draft

VK_NV_dedicated_allocation

Name String

VK_NV_dedicated_allocation

Extension Type

Device extension

Registered Extension Number

27

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • Jeff Bolz @jeffbolznv

Last Modified Date

2016-05-31

IP Status

No known IP claims.

Contributors
  • Jeff Bolz, NVIDIA

This extension allows device memory to be allocated for a particular buf= fer or image resource, which on some devices can significantly improve the performance of that resource. Normal device memory allocations must support memory aliasing and sparse binding, which could interfere with optimizations like framebuffer compression or efficient page table usage. This is important for render targets and very large resources, but need not (and probably should not) be used for smaller resources that can benefit from suballocation.

This extension adds a few small structures to resource creation and memo= ry allocation: a new structure that flags whether am image/buffer will have a dedicated allocation, and a structure indicating the image or buffer that a= n allocation will be bound to.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV=

    • VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV

    • VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV

New Enums

None.

New Functions

None.

Issues

None.

Examples

    // Create an image with
    // VkDedicatedAllocationImageCreateInfoNV::dedi=
catedAllocation
    // set to VK_TRUE

    VkDedicatedAllocationImageCreateInfoNV dedicatedImageInfo =3D
    {
        VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV,       =
     // sType
        NULL,                   =
                                                // =
pNext
        VK_TRUE,                                                           =
     // dedicatedAllocation
    };

    VkImageCreateInfo imageCreateInfo =3D
    {
        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // =
sType
        &dedicatedImageInfo                     // pNext
        // Other members set as usual
    };

    VkImage image;
    VkResult result =3D vkCreateImage(
        device,
        &imageCreateInfo,
        NULL,                   =
    // pAllocator
        &image);

    VkMemoryRequirements memoryRequirements;
    vkGetImageMemoryRequirements(
        device,
        image,
        &memoryRequirements);

    // Allocate memory with VkDedicatedAllocationMe=
moryAllocateInfoNV::image
    // pointing to the image we are allocating the =
memory for

    VkDedicatedAllocationMemoryAllocateInfoNV dedicatedInfo =3D
    {
        VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV,    =
         // sType
        NULL,                   =
                                                    // pNext
        image,                                                             =
         // image
        VK_NULL_HANDLE,                                                    =
         // buffer
    };

    VkMemoryAllocateInfo memoryAllocateInfo =3D
    {
        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,                 // sType
        &dedicatedInfo,                                         // pNext
        memoryRequirements.size,                                // allocationSize
        FindMemoryTypeIndex(memoryRequirements.memoryTypeBits), // memoryTypeIndex
    };

    VkDeviceMemory memory;
    vkAllocateMemory(
        device,
        &memoryAllocateInfo,
        NULL,                   =
    // pAllocator
        &memory);

    // Bind the image to the memory

    vkBindImageMemory(
        device,
        image,
        memory,
        0);

Version History

  • Revision 1, 2016-05-31 (Jeff Bolz)

    • Internal revisions

VK_NV_external_memory

Name String

VK_NV_external_memory

Extension Type

Device extension

Registered Extension Number

57

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • James Jones @cubanismo

Last Modified Date

2016-08-19

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Carsten Rohde, NVIDIA

Applications may wish to export memory to other Vulkan instances or othe= r APIs, or import memory from other Vulkan instances or other APIs to enable Vulkan workloads to be split up across application module, process, or API boundaries. This extension enables applications to create exportable Vulkan memory objects such that the underlying resources can be referenced outside the Vulkan instance that created them.

New Object Types

None.

New Enum Constants

Extending VkStructureType:

  • VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV

  • VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV

New Enums

None.

New Functions

None.

Issues

1) If memory objects are shared between processes and APIs, is this considered aliasing according to the rules outlined in the Memory Aliasing section?

RESOLVED: Yes, but strict exceptions to the rules are a= dded to allow some forms of aliasing in these cases. Further, other extensions may build upon these new aliasing rules to define specific support usage within Vulkan for imported native memory objects, or memory objects from other APIs.

2) Are new image layouts or metadata required to specify image layouts a= nd layout transitions compatible with non-Vulkan APIs, or with other instances of the same Vulkan driver?

RESOLVED: No. Separate instances of the same Vulkan driver running on the same GPU should have identical internal layout semantics, so applictions have the tools the= y need to ensure views of images are consistent between the two instances. Other APIs will fall into two categories: Those that are Vulkan compatible (a term to be defined by subsequent interopability extensions), or Vulkan incompatible. When sharing images with Vulkan incompatible APIs, the Vulkan image must be transitioned to the VK_IMAGE_LAYOUT_GENERAL layout before hand= ing it off to the external API.

Note this does not attempt to address cross-device transitions, nor transitions to engines on the same device which are not visible within the Vulkan API. Both of these are beyond the scope of this extension.

Examples

    // TODO: Write some sample code here.

Version History

  • Revision 1, 2016-08-19 (James Jones)

    • Initial draft

VK_NV_external_memory_capabil= ities

Name String

VK_NV_external_memory_capabilities

Extension Type

Instance extension

Registered Extension Number

56

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
Contact
  • James Jones @cubanismo

Last Modified Date

2016-08-19

IP Status

No known IP claims.

Interactions and External Dependencies
Contributors
  • James Jones, NVIDIA

Applications may wish to import memory from the Direct 3D API, or export memory to other Vulkan instances. This extension provides a set of capability queries that allow applications determine what types of win32 memory handles an implementation supports for a given set of use cases.

New Object Types

None.

New Enum Constants

None.

Issues

1) Why do so many external memory capabilities need to be queried on a per-memory-handle-type basis?

RESOLVED: This is because some handle types are based o= n OS-native objects that have far more limited capabilities than the very generic Vulkan memory objects. Not all memory handle types can name memory objects that support 3D images, for example. Some handle types cannot even support the deferred image and memory binding behavior of Vulkan and require specifying the image when allocating or importing the memory object.

2) Does the VkExternalImageFormatProp= ertiesNV struct need to include a list of memory type bits that support the given handle type?

RESOLVED: No. The memory types that do not support the handle types will simply be filtered out of the results returned by vkGet= ImageMemoryRequirements when a set of handle types was specified at image creation time.

3) Should the non-opaque handle types be moved to their own extension?

RESOLVED: Perhaps. However, defining the handle type bits does very little and does not requir= e any platform-specific types on its own, and it is easier to maintain the bitmask values in a single extension for now. Presumably more handle types could be added by separate extensions though, and it would be midly weird to have some platform-specific ones defined in the core spec and some in extensions

VK_NV_external_memory_win32

Name String

VK_NV_external_memory_win32

Extension Type

Device extension

Registered Extension Number

58

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • James Jones @cubanismo

Last Modified Date

2016-08-19

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Carsten Rohde, NVIDIA

Applications may wish to export memory to other Vulkan instances or othe= r APIs, or import memory from other Vulkan instances or other APIs to enable Vulkan workloads to be split up across application module, process, or API boundaries. This extension enables win32 applications to export win32 handles from Vulkan memory objects such that the underlying resources can be referenced outside the Vulkan instance that created them, and import win32 handles created in the Direct3D API to Vulkan memory objects.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV

    • VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV

New Enums

None.

New Functions

Issues

1) If memory objects are shared between processes and APIs, is this considered aliasing according to the rules outlined in the Memory Aliasing section?

RESOLVED: Yes, but strict exceptions to the rules are a= dded to allow some forms of aliasing in these cases. Further, other extensions may build upon these new aliasing rules to define specific support usage within Vulkan for imported native memory objects, or memory objects from other APIs.

2) Are new image layouts or metadata required to specify image layouts a= nd layout transitions compatible with non-Vulkan APIs, or with other instances of the same Vulkan driver?

RESOLVED: No. Separate instances of the same Vulkan driver running on the same GPU should have identical internal layout semantics, so applictions have the tools the= y need to ensure views of images are consistent between the two instances. Other APIs will fall into two categories: Those that are Vulkan compatible (a term to be defined by subsequent interopability extensions), or Vulkan incompatible. When sharing images with Vulkan incompatible APIs, the Vulkan image must be transitioned to the VK_IMAGE_LAYOUT_GENERAL layout before hand= ing it off to the external API.

Note this does not attempt to address cross-device transitions, nor transitions to engines on the same device which are not visible within the Vulkan API. Both of these are beyond the scope of this extension.

3) Do applications need to call CloseHandle() on the values= returned from vkGetMemoryWin32HandleNV when hand= leType is VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV?

RESOLVED: Yes, unless it is passed back in to another d= river instance to import the object. A successful get call transfers ownership of the handle to the application, while an import transfers ownership to the associated driver. Destroying the memory object will not destroy the handle or the handle=E2= =80=99s reference to the underlying memory resource.

Examples

    //
    // Create an exportable memory object and expor=
t an external
    // handle from it.
    //

    // Pick an external format and handle type.
    static const=
 VkFormat format =3D VK_FORMAT_R8G8B8A8_UNORM;
    static const=
 VkExternalMemoryHandleTypeFlagsNV handleType =3D
        VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV;

    extern VkPhysicalDevice physicalDevice=
;
    extern VkDevice device;

    VkPhysicalDeviceMemoryProperties memoryProperties;
    VkExternalImageFormatPropertiesNV properties;
    VkExternalMemoryImageCreateInfoNV externalMemoryImageCreateInfo;
    VkDedicatedAllocationImageCreateInfoNV dedicatedImageCreateInfo;
    VkImageCreateInfo imageCreateInfo;
    VkImage image;
    VkMemoryRequirements imageMemoryRequirements;
    uint32_t numMemoryTypes;
    uint32_t memoryType;
    VkExportMemoryAllocateInfoNV exportMemoryAllocateInfo;
    VkDedicatedAllocationMemoryAllocateInfoNV dedicatedAllocationInfo;
    VkMemoryAllocateInfo memoryAllocateInfo;
    VkDeviceMemory memory;
    VkResult result;
    HANDLE memoryHnd;

    // Figure out how many memory types the device =
supports
    vkGetPhysicalDeviceMemoryProperties(physicalDevice,
                                        &memoryProperties);
    numMemoryTypes =3D memoryProperties.memoryTypeCount;

    // Check the external handle type capabilities =
for the chosen format
    // Exportable 2D image support with at least 1 =
mip level, 1 array
    // layer, and VK_SAMPLE_COUNT_1_BIT using optim=
al tiling and supporting
    // texturing and color rendering is required.
    result =3D vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
        physicalDevice,
        format,
        VK_IMAGE_TYPE_2D,
        VK_IMAGE_TILING_OPTIMAL,
        VK_IMAGE_USAGE_SAMPLED_BIT |
        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
        0,
        handleType,
        &properties);

    if ((result !=3D VK_SUCCESS) ||
        !(properties.externalMemoryFeatures &
          VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV)) {
        abort();
    }

    // Set up the external memory image creation in=
fo
    memset(&externalMemoryImageCreateInfo,
           0, sizeof=
(externalMemoryImageCreateInfo));
    externalMemoryImageCreateInfo.sType =3D
        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV;
    externalMemoryImageCreateInfo.handleTypes =3D handleType;
    if (properties.externalMemoryFeatures &a=
mp;
        VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV) {
        memset(&dedicatedImageCreateInfo, 0, sizeof(dedicatedImageCreateInfo));
        dedicatedImageCreateInfo.sType =3D
            VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV;
        dedicatedImageCreateInfo.dedicatedAllocation =3D VK_TRUE;
        externalMemoryImageCreateInfo.pNext =3D &dedicatedImageCreateIn=
fo;
    }
    // Set up the  core image creation info
    memset(&imageCreateInfo, 0, sizeof(imageCreateInfo));
    imageCreateInfo.sType =3D VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    imageCreateInfo.pNext =3D &externalMemoryImageCreateInfo;
    imageCreateInfo.format =3D format;
    imageCreateInfo.extent.width =3D 64;
    imageCreateInfo.extent.height =3D 64;
    imageCreateInfo.extent.depth =3D 1;
    imageCreateInfo.mipLevels =3D 1;
    imageCreateInfo.arrayLayers =3D 1;
    imageCreateInfo.samples =3D VK_SAMPLE_COUNT_1_BIT;
    imageCreateInfo.tiling =3D VK_IMAGE_TILING_OPTIMAL;
    imageCreateInfo.usage =3D VK_IMAGE_USAGE_SAMPLED_BIT |
        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    imageCreateInfo.sharingMode =3D VK_SHARING_MODE_EXCLUSIVE;
    imageCreateInfo.initialLayout =3D VK_IMAGE_LAYOUT_UNDEFINED;

    vkCreateImage(device, &imageCreateInfo, NULL, &image);

    vkGetImageMemoryRequirements(device,
                                 image,
                                 &imageMemoryRequirements);

    // For simplicity, just pick the first compatib=
le memory type.
    for (memoryType =3D 0; memoryType < numMemoryTypes; memoryType++) {
        if ((1 << memoryType) & imageMemoryRequirements.memoryTypeBits) {
            break;
        }
    }

    // At least one memory type must be supported g=
iven the prior external
    // handle capability check.
    assert(memoryType < numMemoryTypes);

    // Allocate the external memory object.
    memset(&exportMemoryAllocateInfo, 0,=
 sizeof(exportMemoryAllocateInfo));
    exportMemoryAllocateInfo.sType =3D
        VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV;
    exportMemoryAllocateInfo.handleTypes =3D handleType;
    if (properties.externalMemoryFeatures &a=
mp;
        VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV) {
        memset(&dedicatedAllocationInfo, 0, sizeof(dedicatedAllocationInfo));
        dedicatedAllocationInfo.sType =3D
            VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
        dedicatedAllocationInfo.image =3D image;
        exportMemoryAllocateInfo.pNext =3D &dedicatedAllocationInfo;
    }
    memset(&memoryAllocateInfo, 0, sizeof(memoryAllocateInfo));
    memoryAllocateInfo.sType =3D VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    memoryAllocateInfo.pNext =3D &exportMemoryAllocateInfo;
    memoryAllocateInfo.allocationSize =3D imageMemoryRequirements.size;
    memoryAllocateInfo.memoryTypeIndex =3D memoryType;

    vkAllocateMemory(device, &memoryAllocateInfo, NULL, &memory);

    if (!(properties.externalMemoryFeatures =
&
          VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV)) {
        vkBindImageMemory(device, image, memory, 0<=
/span>);
    }

    // Get the external memory opaque FD handle
    vkGetMemoryWin32HandleNV(device, memory, &memoryHnd);

Version History

  • Revision 1, 2016-08-11 (James Jones)

    • Initial draft

VK_NV_glsl_shader

Name String

VK_NV_glsl_shader

Extension Type

Device extension

Registered Extension Number

13

Revision

1

Extension and Version Dependencies
  • Requires Vulkan 1.0

Deprecation state
  • Deprecated without replacement

Contact
  • Piers Daniell @pdaniell-nv

Last Modified Date

2016-02-14

IP Status

No known IP claims.

Contributors
  • Piers Daniell, NVIDIA

This extension allows GLSL shaders written to the GL_KHR_vulkan_glsl extension specification to be used instead of SPIR-V. The implementation will automatically detect whether the shader is SPIR-V o= r GLSL, and compile it appropriately.

New Object Types

New Enum Constants

  • Extending VkResult:

    • VK_ERROR_INVALID_SHADER_NV

New Enums

New Structures

New Functions

Issues

Examples

Example 1

Passing in GLSL code

    char const vss[] =
=3D
        "#version 450 core\n"
        "layout(location =3D 0) in vec2 aVertex;\n"
        "layout(location =3D 1) in vec4 aColor;\n"
        "out vec4 vColor;\n"
        "void main()\n"
        "{\n"
        "    vColor =3D aColor;\n"
        "    gl_Position =3D vec4(aVertex, 0, 1);\n"
        "}\n"
    ;
    VkShaderModuleCreateInfo vertexShaderInfo =3D { VK_STRUCTURE_TYPE_SHADE=
R_MODULE_CREATE_INFO };
    vertexShaderInfo.codeSize =3D sizeof vss=
;
    vertexShaderInfo.pCode =3D vss;
    VkShaderModule vertexShader;
    vkCreateShaderModule(device, &vertexShaderInfo, 0, &vertexShader);

Version History

  • Revision 1, 2016-02-14 (Piers Daniell)

    • Initial draft

VK_NV_win32_keyed_mutex

Name String

VK_NV_win32_keyed_mutex

Extension Type

Device extension

Registered Extension Number

59

Revision

1

Extension and Version Dependencies
Deprecation state
Contact
  • Carsten Rohde @crohde

Last Modified Date

2016-08-19

IP Status

No known IP claims.

Contributors
  • James Jones, NVIDIA

  • Carsten Rohde, NVIDIA

Applications that wish to import Direct3D 11 memory objects into the Vul= kan API may wish to use the native keyed mutex mechanism to synchronize access to the memory between Vulkan and Direct3D. This extension provides a way for an application to access the keyed mutex associated with an imported Vulkan memory object when submitting command buffers to a queue.

New Object Types

None.

New Enum Constants

  • Extending VkStructureType:

    • VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV=

New Enums

None.

New Functions

None.

Issues

None.

Examples

    //
    // Import a memory object from Direct3D 11, and=
 synchronize
    // access to it in Vulkan using keyed mutex obj=
ects.
    //

    extern VkPhysicalDevice physicalDevice=
;
    extern VkDevice device;
    extern HANDLE sharedNtHandle;

    static const=
 VkFormat format =3D VK_FORMAT_R8G8B8A8_UNORM;
    static const=
 VkExternalMemoryHandleTypeFlagsNV handleType =3D
        VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV;

    VkPhysicalDeviceMemoryProperties memoryProperties;
    VkExternalImageFormatPropertiesNV properties;
    VkExternalMemoryImageCreateInfoNV externalMemoryImageCreateInfo;
    VkImageCreateInfo imageCreateInfo;
    VkImage image;
    VkMemoryRequirements imageMemoryRequirements;
    uint32_t numMemoryTypes;
    uint32_t memoryType;
    VkImportMemoryWin32HandleInfoNV importMemoryInfo;
    VkMemoryAllocateInfo memoryAllocateInfo;
    VkDeviceMemory mem;
    VkResult result;

    // Figure out how many memory types the device =
supports
    vkGetPhysicalDeviceMemoryProperties(physicalDevice,
                                        &memoryProperties);
    numMemoryTypes =3D memoryProperties.memoryTypeCount;

    // Check the external handle type capabilities =
for the chosen format
    // Importable 2D image support with at least 1 =
mip level, 1 array
    // layer, and VK_SAMPLE_COUNT_1_BIT using optim=
al tiling and supporting
    // texturing and color rendering is required.
    result =3D vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
        physicalDevice,
        format,
        VK_IMAGE_TYPE_2D,
        VK_IMAGE_TILING_OPTIMAL,
        VK_IMAGE_USAGE_SAMPLED_BIT |
        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
        0,
        handleType,
        &properties);

    if ((result !=3D VK_SUCCESS) ||
        !(properties.externalMemoryFeatures &
          VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV)) {
        abort();
    }

    // Set up the external memory image creation in=
fo
    memset(&externalMemoryImageCreateInfo,
           0, sizeof=
(externalMemoryImageCreateInfo));
    externalMemoryImageCreateInfo.sType =3D
        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV;
    externalMemoryImageCreateInfo.handleTypes =3D handleType;
    // Set up the  core image creation info
    memset(&imageCreateInfo, 0, sizeof(imageCreateInfo));
    imageCreateInfo.sType =3D VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    imageCreateInfo.pNext =3D &externalMemoryImageCreateInfo;
    imageCreateInfo.format =3D format;
    imageCreateInfo.extent.width =3D 64;
    imageCreateInfo.extent.height =3D 64;
    imageCreateInfo.extent.depth =3D 1;
    imageCreateInfo.mipLevels =3D 1;
    imageCreateInfo.arrayLayers =3D 1;
    imageCreateInfo.samples =3D VK_SAMPLE_COUNT_1_BIT;
    imageCreateInfo.tiling =3D VK_IMAGE_TILING_OPTIMAL;
    imageCreateInfo.usage =3D VK_IMAGE_USAGE_SAMPLED_BIT |
        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    imageCreateInfo.sharingMode =3D VK_SHARING_MODE_EXCLUSIVE;
    imageCreateInfo.initialLayout =3D VK_IMAGE_LAYOUT_UNDEFINED;

    vkCreateImage(device, &imageCreateInfo, NULL, &image);
    vkGetImageMemoryRequirements(device,
                                 image,
                                 &imageMemoryRequirements);

    // For simplicity, just pick the first compatib=
le memory type.
    for (memoryType =3D 0; memoryType < numMemoryTypes; memoryType++) {
        if ((1 << memoryType) & imageMemoryRequirements.memoryTypeBits) {
            break;
        }
    }

    // At least one memory type must be supported g=
iven the prior external
    // handle capability check.
    assert(memoryType < numMemoryTypes);

    // Allocate the external memory object.
    memset(&exportMemoryAllocateInfo, 0,=
 sizeof(exportMemoryAllocateInfo));
    exportMemoryAllocateInfo.sType =3D
        VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV;
    importMemoryInfo.handleTypes =3D handleType;
    importMemoryInfo.handle =3D sharedNtHandle;

    memset(&memoryAllocateInfo, 0, sizeof(memoryAllocateInfo));
    memoryAllocateInfo.sType =3D VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    memoryAllocateInfo.pNext =3D &exportMemoryAllocateInfo;
    memoryAllocateInfo.allocationSize =3D imageMemoryRequirements.size;
    memoryAllocateInfo.memoryTypeIndex =3D memoryType;

    vkAllocateMemory(device, &memoryAllocateInfo, NULL, &mem);

    vkBindImageMemory(device, image, mem, 0)=
;

    ...

    const uint64_t acquireKey =3D 1;
    const uint32_t timeout =3D INFINITE;
    const uint64_t releaseKey =3D 2;

    VkWin32KeyedMutexAcquireReleaseInfoNV keyedMutex =3D
        { VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV };
    keyedMutex.acquireCount =3D 1;
    keyedMutex.pAcquireSyncs =3D &mem;
    keyedMutex.pAcquireKeys =3D &acquireKey;
    keyedMutex.pAcquireTimeoutMilliseconds =3D &timeout;
    keyedMutex.releaseCount =3D 1;
    keyedMutex.pReleaseSyncs =3D &mem;
    keyedMutex.pReleaseKeys =3D &releaseKey;

    VkSubmitInfo submit_info =3D { VK_STRUCTURE_TYPE_SUBMIT_INFO, &keye=
dMutex };
    submit_info.commandBufferCount =3D 1;
    submit_info.pCommandBuffers =3D &cmd_buf;
    vkQueueSubmit(queue, 1, &submit_info=
, VK_NULL_HANDLE);

Version History

  • Revision 2, 2016-08-11 (James Jones)

    • Updated sample code based on the NV external memory extensions.

    • Renamed from NVX to NV extension.

    • Added Overview and Description sections.

    • Updated sample code to use the NV external memory extensions.

  • Revision 1, 2016-06-14 (Carsten Rohde)

    • Initial draft.

Appendix E: API Boilerplate

This appendix defines Vulkan API features that are infrastructure requir= ed for a complete functional description of Vulkan, but do not logically belon= g elsewhere in the Specification.

Vulkan Header Files

Vulkan is defined as an API in the C99 language. Khronos provides a corresponding set of header files for applications using the API, which may be used in either C or C++ code. The interface descriptions in the specification are the same as the interfaces defined in these header files, and both are derived from the vk.xml XML API Registry, which is the canonical machine-readab= le description of the Vulkan API. The Registry, scripts used for processing it into various forms, and documentation of the registry schema are available as described at https://www.khronos.org/registry/vulkan/#apiregistry .

Language bindings for other languages can be defined using the informati= on in the Specification and the Registry. Khronos does not provide any such bindings, but third-party developers have created some additional bindings.

Vulkan Combined API Header vulkan.h (Informative)

Applications normally will include the header vulkan.h. In turn, vulkan.h always includes the following headers:

  • vk_platform.h, defining platform-specific macros and headers.

  • vulkan_core.h, defining APIs f= or the Vulkan core and all registered extensions other than window system-specific extensions.

In addition, specific preprocessor macros defined at the time vulk= an.h is included cause header files for the corresponding w= indow system-specific extension interfaces to be included.

Vulkan Platform-Specific Header vk_platform.h (Informative)

Platform-specific macros and interfaces are defined in vk_platform= .h. These macros are used to control platform-dependent behavior, and their exact definitions are under the control of specific platforms and Vulkan implementations.

Platform-Speci= fic Calling Conventions

On many platforms the following macros are empty strings, causing platfo= rm- and compiler-specific default calling conventions to be used.

VKAPI_ATTR is a macro placed before the return type in Vulk= an API function declarations. This macro controls calling conventions for C++11 and GCC/Clang-style compilers.

VKAPI_CALL is a macro placed after the return type in Vulka= n API function declarations. This macro controls calling conventions for MSVC-style compilers.

VKAPI_PTR is a macro placed between the '(' and '*' in Vulk= an API function pointer declarations. This macro also controls calling conventions, and typically has the same definition as VKAPI_ATTR or VKAPI_CALL, depending= on the compiler.

With these macros, a Vulkan function declaration takes the form of:

VKAPI_ATTR <ret=
urn_type> VKAPI_CALL <command_name>(<command_parameters>);

Additionaly, a Vulkan function pointer type declaration takes the form o= f:

typedef <return_type> (VKAPI_PTR *PFN_<command_name&g=
t;)(<command_parameters>);
Platform-Specific Header Contr= ol

If the VK_NO_STDINT_H macro is defined by the application a= t compile time, extended integer types used by the Vulkan API, such as uint8_t<= /code>, must also be defined by the application. Otherwise, the Vulkan headers will not compile. If VK_NO_STDINT_H is not defined, the system <stdint.= h> is used to define these types. There is a fallback path when Microsoft Visual Studio version 2008 and earlier versions are detected at compile time.

Vulkan Core API Header vulkan_core= .h

Applications that do not make use of window system-specific extensions m= ay simply include vulkan_core.h instead of vulkan.h,= although there is usually no reason to do so. In addition to the Vulkan API, vulkan_core.h also defines a sm= all number of C preprocessor macros that are described below.

Vulkan Version Number Macros

API Version Numbers are packed into integer= s. These macros manipulate version numbers in useful ways.

VK_VERSION_MAJOR extracts the API major version number from= a packed version number:

#define VK_VERSION_MAJOR(version) ((uint32_t)(version) &g=
t;> 22)

VK_VERSION_MINOR extracts the API minor version number from= a packed version number:

#define VK_VERSION_MINOR(version) (((uint32_t)(version) &=
gt;> 12) & 0x3ff<=
/span>)

VK_VERSION_PATCH extracts the API patch version number from= a packed version number:

#define VK_VERSION_PATCH(version) ((uint32_t)(version) &a=
mp; 0xfff)

VK_API_VERSION_1_0 returns the API version number for Vulka= n 1.0. The patch version number in this macro will always be zero. The supported patch version for a physical device = can be queried with vkGetPhysicalDeviceProperties.

// Vulkan 1.0 version number
#define VK_API_VERSION_1_0 VK_MAKE_VERS=
ION(1, 0, 0)// Patch version shou=
ld always be set to 0

VK_API_VERSION_1_1 returns the API version number for Vulka= n 1.1. The patch version number in this macro will always be zero. The supported patch version for a physical device = can be queried with vkGetPhysicalDeviceProperties.

// Vulkan 1.1 version number
#define VK_API_VERSION_1_1 VK_MAKE_VERS=
ION(1, 1, 0)// Patch version shou=
ld always be set to 0

VK_API_VERSION is now commented out of vulkan_core.h<= /code> and cannot be used.

// DEPRECATED: This define has been removed. Specific version defines=
 (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used in=
stead.
//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) /=
/ Patch version should always be set to 0

VK_MAKE_VERSION constructs an API version number.

#define VK_MAKE_VERSION(major, minor, patch) \
    (((major) << 22) | ((minor) <&l=
t; 12) | (patch))
  • major is the major version number.

  • minor is the minor version number.

  • patch is the patch version number.

This macro can be used when constructi= ng the VkApplicationInfo::apiVersion parameter= passed to vkCreateInstance.

Vulkan Header File Version Nu= mber

VK_HEADER_VERSION is the version number of the vulkan= _core.h header. This value is kept synchronized with the patch version of the released Specification.

// Version of this file
#define VK_HEADER_VERSION 82
Vulkan Handle Macros

VK_DEFINE_HANDLE defines a dispatchable handle type.

#define VK_DEFINE_HANDLE(object) =
typedef struct object##_T* object;
  • object is the name of the resulting C type.

The only dispatchable handle types are those related to device and insta= nce management, such as VkDevice.

VK_DEFINE_NON_DISPATCHABLE_HANDLE defines a non-dispatchable handle type.

#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE)
#if defined(__LP64__) || defined(_WIN64=
) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X6=
4) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defin=
ed(__powerpc64__)
        #define VK_DEFINE_NON_DISPATCHA=
BLE_HANDLE(object) typedef struct object##_T *object;
#else
        #define VK_DEFINE_NON_DISPATCHA=
BLE_HANDLE(object) typedef uint64_t object;
#endif
#endif
  • object is the name of the resulting C type.

Most Vulkan handle types, such as VkBuffer, are non-dispat= chable.

Note

The vulkan_core.h header allows the VK_DEFINE_NON_DISPATCHABLE_HANDLE definition to be overridden = by the application. If VK_DEFINE_NON_DISPATCHABLE_HANDLE is already defined when vulkan_core.h is compiled, the default definition is skipped. This allows the application to define a binary-compatible custom handle which may provide more type-safety or oth= er features needed by the application. Behavior is undefined if the application defines a non-binary-compatible handle and may result in memory corruptio= n or application termination. Binary compatibility is platform dependent so the application must be careful if it overrides the default VK_DEFINE_NON_DISPATCHABLE_HANDLE= definition.

VK_NULL_HANDLE is a reserved value representing a non-valid= object handle. It may be passed to and returned from Vulkan commands only when specifically allowed.

#define VK_NULL_HANDLE 0

Window System-Specific Header Control (In= formative)

To use a Vulkan extension supporting a platform-specific window system, header files for that window systems must= be included at compile time, or platform-specific types must be forward-d= eclared. The Vulkan header files cannot determine whether or not an external header is available at compile time, so platform-specific extensions are provided in separate headers from the core API and platform-independent extensions, allowing applications to decide which ones should be defined and how the external headers are included.

Extensions dependent on particular sets of platform headers, or that forward-declare platform-specific types, are declared in a header named for that platform. Before including these platform-specific Vulkan headers, applications must include both vulkan_core.h and any external native headers the= platform extensions depend on.

As a convenience for applications that do not need the flexibility of separate platform-specific Vulkan headers, vulkan.h includes vulkan_core.h, and then conditionally includes platform-specif= ic Vulkan headers and the external headers they depend on. Applications control which platform-specific headers are included by #defining macros before including vulkan.h.

The correspondence between platform-specific extensions, external header= s they require, the platform-specific header which declares them, and the preprocessor macros which enable inclusion by vulkan.h are sho= wn in the following table.

Table 82. Window System Extensions and Headers
Extension Name Window System Name Platform-specific Header Required External Headers Controlling vulkan.h<= /code> Macro

VK_KHR_android_surface

And= roid

vulkan_android.h

Non= e

VK_USE_PLATFORM_ANDROID_KHR

VK_KHR_mir_surface

Mir=

vulkan_mir.h

<mir_toolkit/client_types.h>

VK_USE_PLATFORM_MIR_KHR

VK_KHR_wayland_surface

Way= land

vulkan_wayland.h

<wayland-client.h>

VK_USE_PLATFORM_WAYLAND_KHR

VK_KHR_win32_surface, VK_KHR_external_memory_win32, VK_KHR_win32_keyed_mutex, VK_KHR_external_semaphore_win32, VK_KHR_external_fence_win32= , VK_NV_external_memory_win32= , VK_NV_win32_keyed_mutex

Mic= rosoft Windows

vulkan_win32.h

<windows.h>

VK_USE_PLATFORM_WIN32_KHR

VK_KHR_xcb_surface

X11= Xcb

vulkan_xcb.h

<xcb/xcb.h>

VK_USE_PLATFORM_XCB_KHR

VK_KHR_xlib_surface

X11= Xlib

vulkan_xlib.h

<X11/Xlib.h>

VK_USE_PLATFORM_XLIB_KHR

VK_EXT_acquire_xlib_display

<= /td>

X11= XRAndR

vulkan_xlib_xrandr.h

<X11/Xlib.h>, = <X11/extensions/Xrandr.h>

VK_USE_PLATFORM_XLIB_XRANDR_EXT

VK_MVK_ios_surface

iOS=

vulkan_ios.h

Non= e

VK_USE_PLATFORM_IOS_MVK

VK_MVK_macos_surface

mac= OS

vulkan_macos.h

Non= e

VK_USE_PLATFORM_MACOS_MVK

VK_NN_vi_surface

VI<= /p>

vulkan_vi.h

Non= e

VK_USE_PLATFORM_VI_NN

Note

This section describes the purpose of the headers independently of the specific underlying functionality of the window system extensions themselves. Each extension name will only link to a description of that extension when viewing a specification built with that extension included.

Appendix F: Invariance

The Vulkan specification is not pixel exact. It therefore does not guarantee an exact match between images produced by different Vulkan implementations. However, the specification does specify exact matches, in some cases, for images produced by the same implementation. The purpose of this appendix is to identify and provide justification for those cases that require exact matches.

Repeatability

The obvious and most fundamental case is repeated issuance of a series o= f Vulkan commands. For any given Vulkan and framebuffer state vector, and for any Vulkan command, the resulting Vulkan and framebuffer state must be identical whenever the command is executed on that initial Vulkan and framebuffer state. This repeatability requirement does not apply when using shaders containing side effects (image and buffer variable stores and atomic operations), because these memory operations are not guaranteed to be processed in a defined order.

The repeatability requirement does not apply for rendering done using a graphics pipeline that uses VK_RASTERIZATION_ORDER_RELAXED_AMD= .

One purpose of repeatability is avoidance of visual artifacts when a double-buffered scene is redrawn. If rendering is not repeatable, swapping between two buffers rendered with the same command sequence may result in v= isible changes in the image. Such false motion is distracting to the viewer. Another reason for repeatability is testability.

Repeatability, while important, is a weak requirement. Given only repeatability as a requirement, two scenes rendered with one (small) polygon changed in position might differ at every pixel. Such a difference, while within the law of repeatability, is certainly not within its spirit. Additional invariance rules are desirable to ensure useful operation.

Multi-pass Algorithms

Invariance is necessary for a whole set of useful multi-pass algorithms. Such algorithms render multiple times, each time with a different Vulkan mode vector, to eventually produce a result in the framebuffer. Examples of these algorithms include:

  • =E2=80=9CErasing=E2=80=9D a primitive from the framebuffer by redrawing = it, either in a different color or using the XOR logical operation.

  • Using stencil operations to compute capping planes.

Invariance Rules

For a given Vulkan device:

Rule 1 For any given Vulkan and framebuffer state v= ector, and for any given Vulkan command, the resulting Vulkan and framebuffer state must be identical each time the command is executed on that initial Vulkan and framebuffer state.

Rule 2 Changes to the following state values have n= o side effects (the use of any other state value is not affected by the change):

Required:

  • Color and depth/stencil attachment contents

  • Scissor parameters (other than enable)

  • Write masks (color, depth, stencil)

  • Clear values (color, depth, stencil)

Strongly suggested:

  • Stencil parameters (other than enable)

  • Depth test parameters (other than enable)

  • Blend parameters (other than enable)

  • Logical operation parameters (other than enable)

Corollary 1 Fragment generation is invariant with r= espect to the state values listed in Rule 2.

Rule 3 The arithmetic of each per-fragment operatio= n is invariant except with respect to parameters that directly control it.

Corollary 2 Images rendered into different color at= tachments of the same framebuffer, either simultaneously or separately using the same command sequence, are pixel identical.

Rule 4 Identical pipelines will produce the same re= sult when run multiple times with the same input. The wording =E2=80=9CIdentical pipelines=E2=80=9D means VkPipel= ine objects that have been created with identical SPIR-V binaries and identical state, which are then used by commands executed using the same Vulkan state vector. Invariance is relaxed for shaders with side effects, such as performing stores or atomics.

Rule 5 All fragment shaders that either conditional= ly or unconditionally assign FragCoord.z to FragDepth are depth-invariant with respect to each other, for those fragments where the assignment to FragDepth actually is done.

If a sequence of Vulkan commands specifies primitives to be rendered wit= h shaders containing side effects (image and buffer variable stores and atomi= c operations), invariance rules are relaxed. In particular, rule 1, corollary 2, and rule 4 do not apply in the presence of shader side effects.

The following weaker versions of rules 1 and 4 apply to Vulkan commands involving shader side effects:

Rule 6 For any given Vulkan and framebuffer state v= ector, and for any given Vulkan command, the contents of any framebuffer state not directly or indirectly affected by results of shader image or buffer variable stores or atomic operations must be identical each = time the command is executed on that initial Vulkan and framebuffer state.

Rule 7 Identical pipelines will produce the same re= sult when run multiple times with the same input as long as:

  • shader invocations do not use image atomic operations;

  • no framebuffer memory is written to more than once by image stores, unless all such stores write the same value; and

  • no shader invocation, or other operation performed to process the sequence of commands, reads memory written to by an image store.

Note

The OpenGL spec has the following invariance rule: Consider a primitive = p' obtained by translating a primitive p through an offset (x, y) in window coordinates, where x and y are integers. As long as neither p' nor p is clipped, it must be the case that each fragment f' produced from p' is identical to a corresponding fragment f fro= m p except that the center of f' is offset by (x, y) from the center of f.

This rule does not apply to Vulkan and is an intentional difference from OpenGL.

When any sequence of Vulkan commands triggers shader invocations that perform image stores or atomic operations, and subsequent Vulkan commands read the memory written by those shader invocations, these operations must be explicitly synchronized.

Tessellation Invariance

When using a pipeline containing tessellation evaluation shaders, the fixed-function tessellation primitive generator consumes the input patch specified by an application and emits a new set of primitives. The following invariance rules are intended to provide repeatability guarantees. Additionally, they are intended to allow an application with a carefully crafted tessellation evaluation shader to ensure that the sets of triangles generated for two adjacent patches have identical vertices along shared patch edges, avoiding =E2=80=9Ccracks=E2=80=9D caused by minor differences = in the positions of vertices along shared edges.

Rule 1 When processing two patches with identical o= uter and inner tessellation levels, the tessellation primitive generator will emit an identical set of point, line, or triangle primitives as long as the pipelin= e used to process the patch primitives has tessellation evaluation shaders specifying the same tessellation mode, spacing, vertex order, and point mod= e decorations. Two sets of primitives are considered identical if and only if they contain the same number and type of primitives and the generated tessellation coordinates for the vertex numbered m of the primitive numbered n are identical for all values of m and n.

Rule 2 The set of vertices generated along the oute= r edge of the subdivided primitive in triangle and quad tessellation, and the tessellatio= n coordinates of each, depends only on the corresponding outer tessellation level and the spacing decorations in the tessellation shaders of the pipeline.

Rule 3 The set of vertices generated when subdividi= ng any outer primitive edge is always symmetric. For triangle tessellation, if the subdivision generates a vertex with tessellation coordinates of the form (0, x, 1-x), (x, 0, 1-x), or (x, 1-x, 0), it will also generate a vertex with coordinates of exactly (0, 1-x, x), (1-x, 0, x), or (1-x, x, 0), respectively. For quad tessellation, if the subdivision generates a vertex with coordinates of (x, 0) or (0, x), it will also generate a vertex with coordinates of exactly (1-x, 0) or (0, 1-x), respectively. For isoline tessellation, if it generates vertices at (0, x) and (1, x) where x is not zero, it will also generate vertices at exactly (0, 1-x) and (1, 1-x), respectively.

Rule 4 The set of vertices generated when subdividi= ng outer edges in triangular and quad tessellation must be = independent of the specific edge subdivided, given identical outer tessellation levels and spacing. For example, if vertices at (x, 1 - x, 0) and (1-x, x, 0) are generated whe= n subdividing the w =3D 0 edge in triangular tessellation, vertices must be generated at (x, 0, 1-x) and (1-x, 0, x) when subdividing an otherwise identical v =3D 0 edge. For quad tessellation, if vertices at (x, 0) and (1-x, 0) are generated whe= n subdividing the v =3D 0 edge, vertices must be generated at (0, x) and (0, 1-x) when subdividing an otherwise identical u =3D 0 edge.

Rule 5 When processing two patches that are identic= al in all respects enumerated in rule 1 except for vertex order, the set of triangles generate= d for triangle and quad tessellation must b= e identical except for vertex and triangle order. For each triangle n1 produced by processing the first patch, there must be a triangle n2 produced when processing the second patch each of whose vertices has the same tessellation coordinates as one of the vertices in n1.

Rule 6 When processing two patches that are identic= al in all respects enumerated in rule 1 other than matching outer tessellation levels and/or vertex order, the set of interior triangles generated for triangle and quad tessellation must be identical in all res= pects except for vertex and triangle order. For each interior triangle n1 produced by processing the first patch, there must be a triangle n2 produced when proce= ssing the second patch each of whose vertices has the same tessellation coordinates as one of the vertices in n1. A triangle produced by the tessellator is considered an interior triangle i= f none of its vertices lie on an outer edge of the subdivided primitive.=

Rule 7 For quad and triangle tessellation, the set = of triangles connecting an inner and outer edge depends only on the inner and outer tessellation levels corresponding to that edge and the spacing decorations.=

Rule 8 The value of all defined components of = TessCoord will be in the range [0, 1]. Additionally, for any defined component x of TessCoord, <= em>the results of computing 1.0-x in a tessellation evaluation shader will be exact. If any floating-point values in the range [0, 1] fail to satisfy this property, such values must not be used as= tessellation coordinate components.

Glossary

The terms defined in this section are used consistently throughout this Specification and may be used with or without capitalization.

Accessible (Descriptor Binding)

A descriptor binding is accessible to a shader stage if that stage is included in the stageFlags of the descriptor binding. Descriptors using that binding can only b= e used by stages in which they are accessible.

Acquire Operation (Resource)

An operation that acquires ownership of an image subresource or buffer range.

Adjacent Vertex

A vertex in an adjacency primitive topology that is not part of a given primitive, but is accessible in geometry shaders.

Advanced Blend Operation

Blending performed using one of the blend operation enums introduced by the VK_EXT_blend_operation_advanced<= /a> extension. See Advanced Blending Operations.

Aliased Range (Memory)

A range of a device memory allocation that is bound to multiple resources simultaneously.

Allocation Scope

An association of a host memory allocation to a parent object or command, where the allocation=E2=80=99s lifetime ends before or at the same= time as the parent object is freed or destroyed, or during the parent command.

Aspect (Image)

An image may contain multiple kinds, o= r aspects, of data for each pixel, where each aspect is used in a particular way by the pipeline and may be stored differently or separately f= rom other aspects. For example, the color components of an image format make up the color aspect of the image, and may be used as a= framebuffer color attachment. Some operations, like depth testing, operate only on specific aspects of an image. Others operations, like image/buffer copies, only operate on one aspect at a time.

Attachment (Render Pass)

A zero-based integer index name used in render pass creation to refer to a framebuffer attachment that is accessed by one or more subpasses. The index also refers to an attachment description which includes information about the properties of the image view that will later be attached.

Availability Operation

An operation that causes the values generated by specified memory write accesses to become available for future access.

Available

A state of values written to memory that allows them to be made visible.=

Back-Facing

See Facingness.

Batch

A single structure submitted to a queue as part of a queue submission command, describing a set of queue operations to execute.

Backwards Compatibility

A given version of the API is backwards compatible with an earlier version if an application, relying only on valid behavior and functionality defined by the earlier specification, is able to correctly run against each version without any modification. This assumes no active attempt by that application to not run when it detects a different version.

Full Compatibility

A given version of the API is fully compatible with another version if an application, relying only on valid behavior and functionality defined by either of those specifications, is able to correctly run against each version without any modification. This assumes no active attempt by that application to not run when it detects a different version.

Binding (Memory)

An association established between a range of a resource object and a range of a memory object. These associations determine the memory locations affected by operations performed on elements of a resource object. Memory bindings are established using the vkBindBufferM= emory command for non-sparse buffer objects, using the vkBindI= mageMemory command for non-sparse image objects, and using the vkQueueBindSparse command for sparse resources.

Blend Constant

Four floating point (RGBA) values used as an input to blending.

Blending

Arithmetic operations between a fragment color value and a value in a color attachment that produce a final color value to be written to the attachment.

Buffer

A resource that represents a linear array of data in device memory. Represented by a VkBuffer object.

Buffer View

An object that represents a range of a specific buffer, and state that controls how the contents are interpreted. Represented by a VkBufferView object.

Built-In Variable

A variable decorated in a shader, where the decoration makes the variable take values provided by the execution environment or values that are generated by fixed-function pipeline stages.

Built-In Interface Block

A block defined in a shader that contains only variables decorated with built-in decorations, and is used to match against other shader stages.

Clip Coordinates

The homogeneous coordinate space that vertex positions (Position decoration) are written in by vertex processing stages.

Clip Distance

A built-in output from vertex processing stages that defines a clip half-space against which the primitive is clipped.

Clip Volume

The intersection of the view volume with all clip half-spaces.

Color Attachment

A subpass attachment point, or image view, that is the target of fragment color outputs and blending.

Color Fragment

A unique color value within a pixel of a multisampled color image. The fragment mask will contain indices to the color fragment.

Color Renderable Format

A VkFormat where VK_FORMAT_FEATURE_COLOR_ATTACHMENT_= BIT is set in the optimalTilingFeatures or linearTilingFeatures= member of VkFormatProperties returned by vkGetPhysicalDeviceFormatProperties, depending on the tiling used.

Color Sample Mask

A bitfield associated with a fragment, with one bit for each sample in the color attachment(s). Samples are considered to be covered based on the result of the Coverage Reduction stage. Uncovered samples do not write to color attachments.

Combined Image Sampler

A descriptor type that includes both a sampled image and a sampler.

Command Buffer

An object that records commands to be submitted to a queue. Represented by a VkCommandBuffer object.

Command Pool

An object that command buffer memory is allocated from, and that owns that memory. Command pools aid multithreaded performance by enabling different threads to use different allocators, without internal synchronization on each use. Represented by a VkCommandPool object.

Compatible Allocator

When allocators are compatible, allocations from each allocator can be freed by the other allocator.

Compatible Image Formats

When formats are compatible, images created with one of the formats can have image views created from it using any of the compatible formats. Also see Size-Compatible Image Formats.

Compatible Queues

Queues within a queue family. Compatible queues have identical properties.

Component (Format)

A distinct part of a format. Depth, stencil, and color channels (e.g. R, G, B, A), are all separate components.

Compressed Texel Block

An element of an image having a block-compressed format, comprising a rectangular block of texel values that are encoded as a single value in memory. Compressed texel blocks of a particular block-compressed format have a corresponding width, height, and depth that define the dimensions of these elements in units of texels, and a size in bytes of the encoding in memory.

Coverage

A bitfield associated with a fragment, where each bit is associated to a rasterization sample. Samples are initially considered to be covered based on the result of rasterization, and then coverage can subsequently be turned on or off by other fragment operations or the fragment shader. Uncovered samples do not write to framebuffer attachments.

Cull Distance

A built-in output from vertex processing stages that defines a cull half-space where the primitive is rejected if all vertices have a negative value for the same cull distance.

Cull Volume

The intersection of the view volume with all cull half-spaces.

Decoration (SPIR-V)

Auxiliary information such as built-in variables, stream numbers, invariance, interpolation type, relaxed precision, etc., added to variables or structure-type members through decorations.

Deprecated

A feature is deprecated if it is no longer recommended as the correct or best way to achieve its intended purpose. Generally a newer feature will have been created that solves the same problem - in cases where no newer alternative feature exists, justification should be provided.

Depth/Stencil Attachment

A subpass attachment point, or image view, that is the target of depth and/or stencil test operations and writes.

Depth/Stencil Format

A VkFormat that includes depth and/or stencil components.<= /p>

Depth/Stencil Image (or ImageView)

A VkImage (or VkImageView) with a depth/st= encil format.

Derivative Group

A set of fragment shader invocations that cooperate to compute derivatives, including implicit derivatives for sampled image operations.

Descriptor

Information about a resource or resource view written into a descriptor set that is used to access the resource or view from a shader.

Descriptor Binding

An entry in a descriptor set layout corresponding to zero or more descriptors of a single descriptor type in a set. Defined by a VkDescriptorSetLayoutBinding= structure.

Descriptor Pool

An object that descriptor sets are allocated from, and that owns the storage of those descriptor sets. Descriptor pools aid multithreaded performance by enabling different threads to use different allocators, without internal synchronization on each use. Represented by a VkDescriptorPool object.

Descriptor Set

An object that resource descriptors are written into via the API, and that can be bound to a command buffer suc= h that the descriptors contained within it can be accessed from = shaders. Represented by a VkDescriptorSet object.

Descriptor Set Layout

An object that defines the set of resources (types and counts) and their relative arrangement (in the binding namespace) within a descriptor set. Used when allocating descriptor sets and when creating pipeline layouts. Represented by a VkDescriptorSetLayout object.

Device

The processor(s) and execution environment that perform tasks requested by the application via the Vulkan API.

Device Group

A set of physical devices that support accessing each other=E2=80=99s me= mory and recording a single command buffer that can be executed on all the physical devices.

Device Index

A zero-based integer that identifies one physical device from a logical device. A device index is valid if it is less than the number of physical devices in the logical device.

Device Mask

A bitmask where each bit represents one device index. A device mask value is valid if every bit that is set in the mask is at a bit position that is less than the number of physical devices in the logical device.

Device Memory

Memory accessible to the device. Represented by a VkDeviceMemory object.

Device-Level Command

Any command that is dispatched from a logical device, or from a child object of a logical device.

Device-Level Functionality

All device-level commands and objects, and their structures, enumerated types, and enumerants.

Device-Level Object

Logical device objects and their child objects. For example, VkDevice, VkQueue, and VkCommandBuffer objects are device-level objects.

Device-Local Memory

Memory that is connected to the device, and may= be more performant for device access than host-local memory.

Direct Drawing Commands

Drawing commands that take all their parameters as direct argum= ents to the command (and not sourced via structures in buffer memory as the indirect drawing commands). Includes vkCmdDraw, and vkCmdDrawIndexed.

Disjoint

Disjoint planes are image planes to which memory is bo= und independently.
A disjoint image consists of multiple disjoint planes, an= d is created with the VK_IMAGE_CREATE_DISJOINT_BIT bit set.

Dispatchable Handle

A handle of a pointer handle type which may be used by layers as part of intercepting API commands. The first argument to each Vulkan command is a dispatchable handle type.

Dispatching Commands

Commands that provoke work using a compute pipeline. Includes vkCmdDispatch and vkCmdD= ispatchIndirect.

Drawing Commands

Commands that provoke work using a graphics pipeline. Includes vkCmdDraw, vkCmdDrawIndexed, vkCmdDrawIndirect, vkCmdDrawIndirectCountKHR, vkCmdDrawIndexedIndirectCountKHR, vkCmdDrawIndirectCountAMD, vkCmdDrawIndexedIndirectCountAMD, and vkCmdDrawIndexedIndirect.

Duration (Command)

The duration of a Vulkan command refers to the interval between calling the command and its return to the caller.

Dynamic Storage Buffer

A storage buffer whose offset is specified each time the storage buffer is bound to a command buffer via a descriptor set.

Dynamic Uniform Buffer

A uniform buffer whose offset is specified each time the uniform buffer is bound to a command buffer via a descriptor set.

Dynamically Uniform

See Dynamically Uniform in section 2.2 =E2=80=9CTerms=E2=80=9D = of the Khronos SPIR-V Specification.

Element Size

The size (in bytes) used to store one element of an uncompressed format or the size (in bytes) used to store one block of a block-compressed format.

Explicitly-Enabled Layer

A layer enabled by the application by adding it to the enabled layer list in vkCreateInstance or vkCreateD= evice.

Event

A synchronization primitive that is signaled when execution of previous commands complete through a specified set of pipeline stages. Events can be waited on by the device and polled by the host. Represented by a VkEvent object.

Executable State (Command Buffer)

A command buffer that has ended recording commands and can be executed. See also Initial State and Recording State.

Execution Dependency

A dependency that guarantees that certain pipeline stages=E2=80=99 work = for a first set of commands has completed execution before certain pipeline stages=E2=80=99 work for a second set of commands begins execution. This is accomplished via pipeline barriers, subpass dependencies, events, or implicit ordering operations.

Execution Dependency Chain

A sequence of execution dependencies that transitively act as a single execution dependency.

Explicit chroma reconstruction

An implementation of sampler Y=E2=80=99CBCR conver= sion which reconstructs reduced-resolution chroma samples to luma resolution and then separately performs texture sample interpolation. This is distinct from an implicit implementation, which incorporates chroma sample reconstruction into texture sample interpolation.

Extension Scope

The set of objects and commands that can be affected by an extension. Extensions are either device scope or instance scope.

External Handle

A resource handle which has meaning outside of a specific Vulkan device or its parent instance. External handles may be used to share res= ources between multiple Vulkan devices in different instances, or between Vulkan and other APIs. Some external handle types correspond to platform-defined handles, in which case the resource may outlive any p= articular Vulkan device or instance and may be transferred between p= rocesses, or otherwise manipulated via functionality defined by the platform for that handle type.

External synchronization

A type of synchronization required of = the application, where parameters defined to be externally synchronized must not be used simultaneously in multiple threads.

Facingness (Polygon)

A classification of a polygon as either front-facing or back-facing, depending on the orientation (winding order) of its vertices.

Facingness (Fragment)

A fragment is either front-facing or back-facing, depending on the primitive it was generated from. If the primitive was a polygon (regardless of polygon mode), the fragment inherits the facingness of the polygon. All other fragments are front-facing.

Fence

A synchronization primitive that is signaled when a set of batches or sparse binding operations complete execution on a queue. Fences can be waited on by the host. Represented by a VkFence object.

Flat Shading

A property of a vertex attribute that causes the value from a single vertex (the provoking vertex) to be used for all vertices in a primitive, and for interpolation of that attribute to return that single value unaltered.

Fragment Input Attachment Interface

Variables with UniformConstant storage class and a decorati= on of InputAttachmentIndex that are statically used by a fragment shader=E2=80=99s entry point, which receive values from input attachments.<= /p>

Fragment Mask

A lookup table that associates color samples with color fragment values.=

Fragment Output Interface

A fragment shader entry point=E2=80=99s variables with Output storage class, which output to color and/or depth/stencil attachments.

Framebuffer

A collection of image views and a set of dimensions that, in conjunction with a render pass, define the inputs and outputs used by drawing commands. Represented by a VkFramebuffer object.

Framebuffer Attachment

One of the image views used in a framebuffer.

Framebuffer Coordinates

A coordinate system in which adjacent pixels=E2=80=99 coordinates differ= by 1 in x and/or y, with (0,0) in the upper left corne= r and pixel centers at half-integers.

Framebuffer-Space

Operating with respect to framebuffer coordinates.

Framebuffer-Local

A framebuffer-local dependency guarantees that only for a single framebuffer region, the first set of operations happens-before the second set of operations.

Framebuffer-Global

A framebuffer-global dependency guarantees that for all framebuffer regions, the first set of operations happens-before the second set of operations.

Framebuffer Region

A framebuffer region is a set of sample (x, y, layer, sample) coordinates that is a subset of the entire framebuffer.

Front-Facing

See Facingness.

Global Workgroup

A collection of local workgroups dispatched by a single dispatch command.

Handle

An opaque integer or pointer value used to refer to a Vulkan object. Each object type has a unique handle type.

Happen-after

A transitive, irreflexive and antisymmetric ordering relation between operations. An execution dependency with a source of A and a destinati= on of B enforces that B happens-after A. The inverse relation of happens-before.

Happen-before

A transitive, irreflexive and antisymmetric ordering relation between operations. An execution dependency with a source of A and a destinati= on of B enforces that A happens-before B. The inverse relation of happens-after.

Helper Invocation

A fragment shader invocation that is created solely for the purposes of evaluating derivatives for use in non-helper fragment shader invocations, and which does not have side effects.

Host

The processor(s) and execution environment that the application runs on, and that the Vulkan API is exposed on.

Host Mapped Foreign Memory

Memory owned by a foreign device that is mapped for host access.

Host Memory

Memory not accessible to the device, used to store implementation data structures.

Host-Accessible Subresource

A buffer, or a linear image subresource in either the VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERA= L layout. Host-accessible subresources have a well-defined addressing scheme which can be used by the host.

Host-Local Memory

Memory that is not local to the device, and may= be less performant for device access than device-local memory.

Host-Visible Memory

Device memory that can be mapped on th= e host and can be read and written by the host.

Identically Defined Objects

Objects of the same type where all arguments to their creation or allocation functions, with the exception of pAllocator, are

  1. Vulkan handles which refer to the same object or

  2. identical scalar or enumeration values or

  3. Host pointers which point to an array of values or structures which also satisfy these three constraints.

Image

A resource that represents a multi-dimensional formatted interpretation of device memory. Represented by a VkImage object.

Image Subresource

A specific mipmap level and layer of an image.

Image Subresource Range

A set of image subresources that are contiguous mipmap levels and layers.

Image View

An object that represents an image subresource range of a specific image, and state that controls how the contents are interpreted. Represented by a VkImageView object.

Immutable Sampler

A sampler descriptor provided at descriptor set layout creation time, and that is used for that binding in all descriptor sets allocated from the layout, and cannot be changed.

Implicit chroma reconstruction

An implementation of sampler Y=E2=80=99CBCR conver= sion which reconstructs the reduced-resolution chroma samples directly at the sample point, as part of the normal texture sampling operation. This is distinct from an explicit chroma reconstruction implementation, which reconstructs the reduced-resolution chroma samples to the resolution of the luma samples, then filters the result as part of texture sample interpolation.

Implicitly-Enabled Layer

A layer enabled by a loader-defined mechanism outside the Vulkan API, rather than explicitly by the application during instance or device creation.

Index Buffer

A buffer bound via vkCmdBindIndexBuffer which = is the source of index values used to fetch vertex attributes for a vkCmdDrawIndexed or vkCmdDr= awIndexedIndirect command.

Indexed Drawing Commands

Drawing commands which use an index buffer as the sour= ce of index values used to fetch vertex attributes for a drawing command. Includes vkCmdDrawIndexed, vkCmdDrawIndexedIndirectCountKHR, vkCmdDrawIndexedIndirectCountAMD, and vkCmdDrawIndexedIndirect.

Indirect Commands

Drawing or dispatching commands that source some of their parameters from structures in buffer memory. Includes vkCmdDrawIndirect, vkCmdDrawIndirectCountKHR, vkCmdDrawIndexedIndirectCountKHR, vkCmdDrawIndirectCountAMD, vkCmdDrawIndexedIndirectCountAMD, and vkCmdDispatchIndirect.

Indirect Commands Layout

A definition of a sequence of commands, that are generated on the device via vkCmdProcessCommandsNVX. Each sequence is comprised of multiple VkIndirectCommandsTokenTypeNVX, which r= epresent a subset of traditional command buffer commands. Represented as VkIndirectCommandsLayoutNVX= .

Indirect Drawing Commands

Drawing commands that source some of their parameters from stru= ctures in buffer memory. Includes vkCmdDrawIndirect, vkCmdDrawIndirectCountKHR, vkCmdDrawIndexedIndirectCountKHR, vkCmdDrawIndirectCountAMD, vkCmdDrawIndexedIndirectCountAMD, and vkCmdDrawIndexedIndirect.

Initial State (Command Buffer)

A command buffer that has not begun recording commands. See also Recorded State and Executable State.

Input Attachment

A descriptor type that represents an image view, and supports unfiltered read-only access in a shader, only at the fragment=E2=80=99s location in th= e view.

Instance

The top-level Vulkan object, which represents the application=E2=80=99s connection to the implementation. Represented by a VkInstance object.

Instance-Level Command

Any command that is dispatched from an instance, or from a child object of an instance, except for physical devices and their children.

Instance-Level Functionality

All instance-level commands and objects, and their structures, enumerated types, and enumerants.

Instance-Level Object

High-level Vulkan objects, which are not physical devices, nor children of physical devices. For example, VkInstance is an instance-level object.

Instance (Memory)

In a logical device representing more than one physical device, some device memory allocations have the requested amount of memory allocated multiple times, once for each physical device in a device mask. Each such replicated allocation is an instance of the device memory.

Instance (Resource)

In a logical device representing more than one physical device, buffer and image resources exist on all physical devices but can be bound to memory differently on each. Each such replicated resource is an instance of the resource.

Internal Synchronization

A type of synchronization required of = the implementation, where parameters not defined to be externally synchronized may require internal mutexing to avoid multithreaded race conditions.

Invocation (Shader)

A single execution of an entry point in a SPIR-V module. For example, a single vertex=E2=80=99s execution of a vertex shader or a si= ngle fragment=E2=80=99s execution of a fragment shader.

Invocation Group

A set of shader invocations that are executed in parallel and that must execute the same control flow path in order for control flow to be considered dynamically uniform.

Linear Resource

A resource is linear if it is a VkBuffer, or a VkImage created with VK_IMAGE_TILING_LINEAR. A resource is non-linear if it is a VkImage created w= ith VK_IMAGE_TILING_OPTIMAL.

Local Workgroup

A collection of compute shader invocations invoked by a single dispatch command, which share data via WorkgroupLocal variables and can synchronize with each other.

Logical Device

An object that represents the application=E2=80=99s interface to the phy= sical device. The logical device is the parent of most Vulkan objects. Represented by a VkDevice object.

Logical Operation

Bitwise operations between a fragment color value and a value in a color attachment, that produce a final color value to be written to the attachment.

Lost Device

A state that a logical device may be i= n as a result of unrecoverable implementation errors, or other exceptional conditions.

Mappable

See Host-Visible Memory.

Memory Dependency

A memory dependency is an execution dependency which includes availability and visibility operations such that:

  • The first set of operations happens-before the availability operation

  • The availability operation happens-before the visibility operation

  • The visibility operation happens-before the second set of operations

Memory Heap

A region of memory from which device memory allocations can be made.

Memory Type

An index used to select a set of memory properties (e.g. mappable, cached) for a device memory allocation.

Mip Tail Region

The set of mipmap levels of a sparse residency texture that are too small to fill a sparse block, and that must all be bound to memory collectively and opaquely.

Multi-planar

A multi-planar format (or =E2=80=9Cplanar format=E2=80=9D) is a= n image format consisting of more than one plane, identifiable with a _2PLA= NE or _3PLANE component to the format name and listed in Formats requiring samp= ler Y=E2=80=99CBCR conversion for VK_IMAGE_ASPE= CT_COLOR_BIT image views. A multi-planar image (or =E2=80=9Cplanar image=E2=80=9D) is an ima= ge of a multi-planar format.

Non-Dispatchable Handle

A handle of an integer handle type. Handle values may not be unique, even for= two objects of the same type.

Non-Indexed Drawing Commands

Drawing commands for which the vertex attributes are sourced in= linear order from the vertex input attributes for a drawing command (i.e. they do not use an index buffer). Includes vkCmdDraw, vkCmdDrawIndirectCountKHR, vkCmdDrawIndirectCountAMD, and vkCmdDrawIndirect.

Normalized

A value that is interpreted as being in the range [0,= 1] as a result of being implicitly divided by some other value.

Normalized Device Coordinates

A coordinate space after perspective division is applied to clip coordinates, and before the viewport transformation converts to framebuffer coordinates.

Object Table

A binding table for various resources (VkPipeline, VkBuffer, VkDescriptorSet), so that they can be referenced in device-generated command processing. Represented as VkObjectTableNVX. Entries are registered or unregistered via uint32_t indices.

Obsoleted

A feature is obsolete if it can no longer be used. For core features, making one obsolete would be in violation of the compatibility rules, so must not be done. However extensions do not have these guarantees, and can be made obsolete by a newer core version or extension.

Overlapped Range (Aliased Range)

The aliased range of a device memory allocation that intersects a given image subresource of an image or range of a buffer.

Ownership (Resource)

If an entity (e.g. a queue family) has ownership of a resource, access to that resource is well-defined for access by that entity.

Packed Format

A format whose components are stored as a single data element in memory, with their relative locations defined within that element.

Passthrough Geometry Shader

A geometry shader which uses the PassthroughNV decoration o= n a variable in its input interface. Output primitives in a passthrough geometry shader always have the same topology as the input primitive and are not produced by emitting vertices.

Payload

Importable or exportable reference to the internal data of an object in Vulkan.

Peer Memory

An instance of memory corresponding to a different physical device than the physical device performing the memory access, in a logical device that represents multiple physical devices.

Physical Device

An object that represents a single device in the system. Represented by a VkPhysicalDevice object.

Physical-Device-Level Command

Any command that is dispatched from a physical device.

Physical-Device-Level Functionality

All physical-device-level commands and objects, and their structures, enumerated types, and enumerants.

Physical-Device-Level Object

Physical device objects. For example, VkPhysicalDevice is a physical-device-le= vel object.

Pipeline

An object that controls how graphics or compute work is executed on the device. A pipeline includes one or more shaders, as well as state controlling any non-programmable stages of the pipeline. Represented by a VkPipeline object.

Pipeline Barrier

An execution and/or memory dependency recorded as an explicit command in a command buffer, that forms a dependency between the previous and subsequent commands.

Pipeline Cache

An object that can be used to collect = and retrieve information from pipelines as they are created, and can be= populated with previously retrieved information in order to accelerate pipeline creation. Represented by a VkPipelineCache object.

Pipeline Layout

An object that defines the set of resources (via a collection of descriptor set layouts) and push constants used by pipelines that are created using the layout. Used when creating a pipeline and when binding descriptor sets and setting push constant values. Represented by a VkPipelineLayout object.

Pipeline Stage

A logically independent execution unit that performs some of the operations defined by an action command.

pNext Chain

A set of structures chained together through their pNext members.

Planar

See multi-planar.

Plane

An image plane is part of the representation of an image, conta= ining a subset of the color channels required to represent the texels in the image and with a contiguous mapping of coordinates to bound memory. Most images consist only of a single plane, but some formats spread the channels across multiple image planes. The host-accessible properties of each image plane are accessed in a linear layout using vkGetImageSubresourceLayou= t. If a multi-planar image is created with the VK_IMAGE_CREATE_DISJOINT_BIT bit set, the image is described a= s disjoint, and its planes are therefore are bound to memory independently.

Point Sampling (Rasterization)

A rule that determines whether a fragment sample location is covered by a polygon primitive by testing whether the sample location is in the interior of the polygon in framebuffer-space, or on the boundary of the polygon according to the tie-breaking rules.

Presentable image

A VkImage object obtained from a VkSwapchainKHR used to present to a VkSurfaceKHR object.

Preserve Attachment

One of a list of attachments in a subpass description that is not read or written by the subpass, but that is read or written on earlier and later subpasses and whose contents must b= e preserved through this subpass.

Primary Command Buffer

A command buffer that can execute seco= ndary command buffers, and can be submitted directly to a queue.

Primitive Topology

State that controls how vertices are assembled into primitives, e.g. as lists of triangles, strips of lines, etc..

Promoted

A feature is promoted if it is taken from an older extension and made available as part of a new core version of the API, or a newer extension that is considered to be either as widely supported or more so. A promoted feature may have minor differences from the original such as:

  • It may be renamed

  • A small number of non-intrusive parameters may have been added

  • The feature may be advertised differently by device features

  • The author ID suffixes will be changed or removed as appropriate

Protected Buffer

A buffer to which protected device memory can be bound.

Protected-capable Device Queue

A device queue to which protected command buffers can be submitted.

Protected Command Buffer

A command buffer which can be submitte= d to a protected-capable device queue.

Protected Device Memory

Device memory which can be visible to = the device but must not be visible to the host.

Protected Image

An image to which protected device memory can be bound.

Provoking Vertex

The vertex in a primitive from which flat shaded attribute values are taken. This is generally the =E2=80=9Cfirst=E2=80=9D vertex in the primitive, and = depends on the primitive topology.

Push Constants

A small bank of values writable via the API and accessible in shaders. Push constants allow the application to set values used in shaders without creating buffers or modifying and binding descriptor sets for each update.

Push Constant Interface

The set of variables with PushConstant storage class that a= re statically used by a shader entry point, and which receive values from push constant commands.

Push Descriptors

Descriptors that are written directly into a command buffer rather than into a descriptor set. Push descriptors allow the application to set descriptors used in shaders without allocating or modifying descriptor sets for each update.

Descriptor Update Template

An object that specifies a mapping from descriptor update information in host memory to elements in a descriptor set, which helps enable more efficient descriptor set updates.

Query Pool

An object that contains a number of query entries and their associated state and results. Represented by a VkQueryPool object.

Queue

An object that executes command buffers and sparse binding operations on a device. Represented by a VkQueue object.

Queue Family

A set of queues that have common properties and support the same functionality, as advertised in VkQueueFamilyPrope= rties.

Queue Operation

A unit of work to be executed by a specific queue on a device, submitted via a queue submission command. Each queue submission command details the specific queue operations that occur as a result of calling that command. Queue operations typically include work that is specific to each command, and synchronization tasks.

Queue Submission

Zero or more batches and an optional fence to be signaled, passed to a command for execution on a queue. See the Devices and Queues chapter for more information.

Recording State (Command Buffer)

A command buffer that is ready to record commands. See also Initial State and Executable State.

Release Operation (Resource)

An operation that releases ownership of an image subresource or buffer range.

Render Pass

An object that represents a set of framebuffer attachments and phases of rendering using those attachments. Represented by a VkRenderPass object.

Render Pass Instance

A use of a render pass in a command buffer.

Required Extensions

Extensions that must be enabled alongs= ide extensions dependent on them (see Extension Dependencies).

Reset (Command Buffer)

Resetting a command buffer discards any previously recorded commands and puts a command buffer in the initial state.

Residency Code

An integer value returned by sparse image instructions, indicating whether any sparse unbound texels were accessed.

Resolve Attachment

A subpass attachment point, or image view, that is the target of a multisample resolve operation from the corresponding color attachment at the end of the subpass.

Retired Swapchain

A swapchain that has been used as the oldSwapchain paramete= r to vkCreateSwapchainKHR. Images cannot be acquired from a retired swapchain, however images that were acquired (but not presented) before the swapchain was retired can be presented.

Sampled Image

A descriptor type that represents an image view, and supports filtered (sampled) and unfiltered read-only access in a shader.

Sampler

An object that contains state that controls how sampled image data is sampled (or filtered) when accessed in a shader. Also a descriptor type describing the object. Represented by a VkSampler object.

Secondary Command Buffer

A command buffer that can be executed = by a primary command buffer, and must not be submitted directly to a queue= .

Self-Dependency

A subpass dependency from a subpass to itself, i.e. with srcSubpass equal to dstSubpass. A self-dependency is not automatically performed during a render pass instance, rather a subset of it can be pe= rformed via vkCmdPipelineBarrier during the subpass.

Semaphore

A synchronization primitive that supports signal and wait operations, and can be used to synchronize operations= within a queue or across queues. Represented by a VkSemaphore object.

Shader

Instructions selected (via an entry point) from a shader module, which are executed in a shader stage.

Shader Code

A stream of instructions used to describe the operation of a shader.

Shader Module

A collection of shader code, potentially including several functions and entry points, that is used to create shaders in pipelines. Represented by a VkShaderModule object.

Shader Stage

A stage of the graphics or compute pipeline that executes shader code.

Shared presentable image

A presentable image created from a swapchain with VkPr= esentModeKHR set to either VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR or VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR.

Side Effect

A store to memory or atomic operation on memory from a shader invocation.

Single-plane format

A format that is not multi-planar.

Size-Compatible Image Formats

When a compressed image format and an uncompressed image format are size-compatible, it means that the element size of the uncompressed format must equal the element size (compr= essed texel block size) of the compressed format.

Sparse Block

An element of a sparse resource that can be independently bound to memory. Sparse blocks of a particular sparse resource have a corresponding size in bytes that they use in the bound memory.

Sparse Image Block

A sparse block in a sparse partially-resident image. In addition to the sparse block size in bytes, sparse image blocks have a corresponding width, height, and depth that define the dimensions of these elements in units of texels or compressed texel blocks, the latter being used in case of sparse images having a block-compressed format.

Sparse Unbound Texel

A texel read from a region of a sparse texture that does not have memory bound to it.

Static Use

An object in a shader is statically used by a shader entry point if any function in the entry point=E2=80=99s call tree contains an instruction usi= ng the object. Static use is used to constrain the set of descriptors used by a shader entry point.

Storage Buffer

A descriptor type that represents a buffer, and supports reads, writes, and atomics in a shader.

Storage Image

A descriptor type that represents an image view, and supports unfiltered loads, stores, and atomics in a shader.

Storage Texel Buffer

A descriptor type that represents a buffer view, and supports unfiltered, formatted reads, writes, and atomics in a shader.

Subgroup

A set of shader invocations that can s= ynchronize and share data with each other efficiently. In compute shaders, the local workgroup is a superset of the subgr= oup.

Subgroup Mask

A bitmask for all invocations in the current subgroup with one bit per invocation, starting with the least significant bit in the first vector component, continuing to the last bit (less than SubgroupSize)= in the last required vector component.

Subpass

A phase of rendering within a render pass, that reads and writes a subset of the attachments.

Subpass Dependency

An execution and/or memory dependency between two subpasses described as part of render pass creation, and automatically performed between subpasses in a render pass instance. A subpass dependency limits the overlap of execution of the pair of subpasses, and can provide guarantees of = memory coherence between accesses in the subpasses.

Subpass Description

Lists of attachment indices for input attachments, color attachments, depth/stencil attachment, resolve attachments, and preserve attachments used by the subpass in a render pass.

Subset (Self-Dependency)

A subset of a self-dependency is a pipeline barrier performed during the subpass of the self-dependency, and whose stage masks and access masks each contain a subset of the bits set in the identically named mask in the self-dependency.

Texel Coordinate System

One of three coordinate systems (normalized, unnormalized, integer) that define how texel coordinates are interpreted in an image or a specific mipmap level of an image.

Uniform Texel Buffer

A descriptor type that represents a buffer view, and supports unfiltered, formatted, read-only access in a shader.

Uniform Buffer

A descriptor type that represents a buffer, and supports read-only access in a shader.

Units in the Last Place (ULP)

A measure of floating-point error loosely defined as the smallest representable step in a floating-point format near a given value. For the precise definition see Precision and Operation of SPIR-V instructions or Jean-Michel Muller, "On the definition of ulp(x).", RR-5504, INRIA. Other sources may also use the term "unit of least precision".

Unnormalized

A value that is interpreted according to its conventional interpretation, and is not normalized.

Unprotected Buffer

A buffer to which unprotected device memory can= be bound.

Unprotected Command Buffer

A command buffer which can be submitte= d to an unprotected device queue or a protected-capable device queue.

Unprotected Device Memory

Device memory which can be visible to = the device and can be visible to the host.

Unprotected Image

An image to which unprotected device memory can= be bound.

User-Defined Variable Interface

A shader entry point=E2=80=99s variables with Input or Output storage class that are not built-in variables.

Vertex Input Attribute

A graphics pipeline resource that produces input values for the vertex shader by reading data from a vertex input binding and converting it to the attribute=E2=80=99s format.

Validation Cache

An object that can be used to collect = and retrieve validation results from the validation layers, and can be po= pulated with previously retrieved results in order to accelerate the validation process. Represented by a VkValidationCacheEXT object.

Vertex Input Binding

A graphics pipeline resource that is bound to a buffer and includes state that affects addressing calculations within that buffer.

Vertex Input Interface

A vertex shader entry point=E2=80=99s variables with Input = storage class, which receive values from vertex input attributes.

Vertex Processing Stages

A set of shader stages that comprises the vertex shader, tessellation control shader, tessellation evaluation shader, and geometry shader stages.

View Mask

When multiview is enabled, a view mask is a property of a subpass controlling which views the rendering commands are broadcast to.

View Volume

A subspace in homogeneous coordinates, corresponding to post-projection x and y values between -1 and +1, and z values between 0 and +1.

Viewport Transformation

A transformation from normalized device coordinates to framebuffer coordinates, based on a viewport rectangle and depth range.

Visibility Operation

An operation that causes available values to become visible to specified memory accesses.

Visible

A state of values written to memory that allows them to be accessed by a set of operations.

Common Abbreviations

Abbreviations and acronyms are sometimes used in the Specification and t= he API where they are considered clear and commonplace, and are defined here:<= /p>

Src

Source

Dst

Destination

Min

Minimum

Max

Maximum

Rect

Rectangle

Info

Information

LOD

Level of Detail

ID

Identifier

UUID

Universally Unique Identifier

Op

Operation

R

Red color component

G

Green color component

B

Blue color component

A

Alpha color component

Prefixes

Prefixes are used in the API to denote specific semantic meaning of Vulk= an names, or as a label to avoid name clashes, and are explained here:

VK/Vk/vk

Vulkan namespace
All types, commands, enumerants and defines in this specification are prefixed with these two characters.

PFN/pfn

Function Pointer
Denotes that a type is a function pointer, or that a variable is of a pointer type.

p

Pointer
Variable is a pointer.

vkCmd

Commands that record commands in command buffers
These API commands do not result in immediate processing on the device. Instead, they record the requested action in a command buffer for execution when the command buffer is submitted to a queue.

s

Structure
Used to denote the VK_STRUCTURE_TYPE* member of each structure= in sType

Appendix G: Credits (Informative)

Vulkan 1.1 is the result of contributions from many people and companies participating in the Khronos Vulkan Working Group, as well as input from th= e Vulkan Advisory Panel.

Members of the Working Group, including the company that they represente= d at the time of their most recent contribution, are listed in the following sections. Some specific contributions made by individuals are listed together with their name.

Working Group = Contributors to Vulkan 1.1 and 1.0

  • Adam Jackson, Red Hat

  • Alexander Galazin, Arm

  • Alex Bourd, Qualcomm Technologies, Inc.

  • Alon Or-bach, Samsung Electronics (WSI technical sub-group chair)

  • Andrew Garrard, Samsung Electronics (format wrangler)

  • Andrew Woloszyn, Google

  • Antoine Labour, Google

  • Bill Licea-Kane, Qualcomm Technologies, Inc.

  • Cass Everitt, Oculus VR

  • Chad Versace, Google

  • Christophe Riccio, Unity Technologies

  • Dan Baker, Oxide Games

  • Dan Ginsburg, Valve Software

  • Daniel Johnston, Intel

  • Daniel Koch, NVIDIA (Shader Interfaces; Features, Limits, and Formats)

  • Daniel Rakos, AMD

  • David Airlie, Red Hat

  • David Miller, Miller & Mattson (Vulkan reference card)

  • David Neto, Google

  • Dominik Witczak, AMD

  • Graeme Leese, Broadcom

  • Graham Sellers, AMD

  • Ian Romanick, Intel

  • James Jones, NVIDIA

  • Jan-Harald Fredriksen, Arm

  • Jan Hermes, Continental Corporation

  • Jason Ekstrand, Intel

  • Jeff Bolz, NVIDIA (extensive contributions, exhaustive review and rewrites for technical correctness)

  • Jeff Juliano, NVIDIA

  • Jesse Barker, Unity Technologies

  • Jesse Hall, Google

  • Johannes van Waveren, Oculus VR

  • John Kessenich, Google (SPIR-V and GLSL for Vulkan spec author)

  • John McDonald, Valve Software

  • Jonas Gustavsson, Samsung Electronics

  • Jon Ashburn, LunarG

  • Jon Leech, Independent (XML toolchain, normative language, release wrangler)

  • Jungwoo Kim, Samsung Electronics

  • Kathleen Mattson, Miller & Mattson (Vulkan reference card)

  • Kenneth Benzie, Codeplay Software Ltd.

  • Kerch Holt, NVIDIA (SPIR-V technical sub-group chair)

  • Kristian Kristensen, Intel

  • Mark Lobodzinski, LunarG

  • Mathias Heyer, NVIDIA

  • Mathias Schott, NVIDIA

  • Maurice Ribble, Qualcomm Technologies, Inc.

  • Michael Worcester, Imagination Technologies

  • Mika Isojarvi, Google

  • Mitch Singer, AMD

  • Neil Henning, Codeplay Software Ltd.

  • Neil Trevett, NVIDIA

  • Norbert Nopper, Independent

  • Pierre Boudier, NVIDIA

  • Pierre-Loup Griffais, Valve Software

  • Piers Daniell, NVIDIA (dynamic state, copy commands, memory types)

  • Pyry Haulos, Google (Vulkan conformance test subcommittee chair)

  • Ray Smith, Arm

  • Robert Simpson, Qualcomm Technologies, Inc.

  • Rolando Caloca Olivares, Epic Games

  • Sean Harmer, KDAB Group

  • Shannon Woods, Google

  • Slawomir Cygan, Intel

  • Slawomir Grajewski, Intel

  • Stuart Smith, Imagination Technologies

  • Timothy Lottes, AMD

  • Tobias Hector, Imagination Technologies (validity language and toolchain)

  • Tom Olson, Arm (working group chair)

  • Tony Barbour, LunarG

  • Yanjun Zhang, VeriSilicon

Working Group Contribu= tors to Vulkan 1.1

  • Aaron Greig, Codeplay Software Ltd.

  • Aaron Hagan, AMD

  • Alan Ward, Google

  • Alejandro Pi=C3=B1eiro, Igalia

  • Andres Gomez, Igalia

  • Baldur Karlsson, Independent

  • Barthold Lichtenbelt, NVIDIA

  • Bas Nieuwenhuizen, Google

  • Bill Hollings, Brenwill

  • Colin Riley, AMD

  • Cort Stratton, Google

  • Courtney Goeltzenleuchter, Google

  • Dae Kim, Imagination Technologies

  • Daniel Stone, Collabora

  • David Pinedo, LunarG

  • Dejan Mircevski, Google

  • Dzmitry Malyshau, Mozilla

  • Erika Johnson, LunarG

  • Greg Fischer, LunarG

  • Hans-Kristian Arntzen, Arm

  • Iago Toral, Igalia

  • Ian Elliott, Google

  • Jeff Leger, Qualcomm Technologies, Inc.

  • Jeff Vigil, Samsung Electronics

  • Jens Owen, Google

  • Joe Davis, Samsung Electronics

  • John Zulauf, LunarG

  • Jordan Justen, Intel

  • J=C3=B6rg Wagner, Arm

  • Kalle Raita, Google

  • Karen Ghavam, LunarG

  • Karl Schultz, LunarG

  • Kenneth Russell, Google

  • Kevin O=E2=80=99Neil, AMD

  • Lauri Ilola, Nokia

  • Lenny Komow, LunarG

  • Lionel Landwerlin, Intel

  • Maciej Jesionowski, AMD

  • Mais Alnasser, AMD

  • Marcin Rogucki, Mobica

  • Mark Callow, Independent

  • Mark Kilgard, NVIDIA

  • Markus Tavenrath, NVIDIA

  • Mark Young, LunarG

  • Matth=C3=A4us Chajdas, AMD

  • Matt Netsch, Qualcomm Technologies, Inc.

  • Michael O=E2=80=99Hara, AMD

  • Michael Wong, Codeplay Software Ltd.

  • Mike Schuchardt, LunarG

  • Mike Weiblen, LunarG

  • Nicolai H=C3=A4hnle, AMD

  • Nuno Subtil, NVIDIA

  • Patrick Cozzi, Independent

  • Petros Bantolas, Imagination Technologies

  • Ralph Potter, Codeplay Software Ltd.

  • Rob Barris, NVIDIA

  • Ruihao Zhang, Qualcomm Technologies, Inc.

  • Sorel Bosan, AMD

  • Stephen Huang, Mediatek

  • Tilmann Scheller, Samsung Electronics

  • Tomasz Bednarz, Independent

  • Victor Eruhimov, ???

  • Wolfgang Engel, ???

Working Group Contribu= tors to Vulkan 1.0

  • Adam =C5=9Amigielski, Mobica

  • Allen Hux, Intel

  • Andrew Cox, Samsung Electronics

  • Andrew Poole, Samsung Electronics

  • Andrew Rafter, Samsung Electronics

  • Andrew Richards, Codeplay Software Ltd.

  • Aras Pranckevi=C4=8Dius, Unity Technologies

  • Ashwin Kolhe, NVIDIA

  • Ben Bowman, Imagination Technologies

  • Benj Lipchak

  • Bill Hollings, The Brenwill Workshop

  • Brent E. Insko, Intel

  • Brian Ellis, Qualcomm Technologies, Inc.

  • Cemil Azizoglu, Canonical

  • Chang-Hyo Yu, Samsung Electronics

  • Chia-I Wu, LunarG

  • Chris Frascati, Qualcomm Technologies, Inc.

  • Cody Northrop, LunarG

  • Courtney Goeltzenleuchter, LunarG

  • Damien Leone, NVIDIA

  • David Mao, AMD

  • David Yu, Pixar

  • Frank (LingJun) Chen, Qualcomm Technologies, Inc.

  • Fred Liao, Mediatek

  • Gabe Dagani, Freescale

  • Graham Connor, Imagination Technologies

  • Hwanyong Lee, Kyungpook National University

  • Ian Elliott, LunarG

  • James Hughes, Oculus VR

  • Jeff Vigil, Qualcomm Technologies, Inc.

  • Jens Owen, LunarG

  • Jeremy Hayes, LunarG

  • Jonathan Hamilton, Imagination Technologies

  • Krzysztof Iwanicki, Samsung Electronics

  • Larry Seiler, Intel

  • Lutz Latta, Lucasfilm

  • Maria Rovatsou, Codeplay Software Ltd.

  • Mark Callow

  • Mateusz Przybylski, Intel

  • Maxim Lukyanov, Samsung Electronics

  • Michael Lentine, Google

  • Michal Pietrasiuk, Intel

  • Mike Stroyan, LunarG

  • Minyoung Son, Samsung Electronics

  • Mythri Venugopal, Samsung Electronics

  • Naveen Leekha, Google

  • Nick Penwarden, Epic Games

  • Niklas Smedberg, Unity Technologies

  • Pat Brown, NVIDIA

  • Patrick Doane, Blizzard Entertainment

  • Peter Lohrmann, Valve Software

  • Piotr Bialecki, Intel

  • Prabindh Sundareson, Samsung Electronics

  • Rob Stepinski, Transgaming

  • Roy Ju, Mediatek

  • Rufus Hamede, Imagination Technologies

  • Sean Ellis, Arm

  • Stefanus Du Toit, Google

  • Steve Hill, Broadcom

  • Steve Viggers, Core Avionics & Industrial Inc.

  • Tim Foley, Intel

  • Timo Suoranta, AMD

  • Tobin Ehlis, LunarG

  • Tomasz Kubale, Intel

  • Wayne Lister, Imagination Technologies

Other Credits

In addition to the Working Group, the Vulkan Advisory Panel members prov= ided important real-world usage information and advice that helped guide design decisions.

Administrative support to the Working Group for Vulkan 1.1 was provided = by Khronos staff including Angela Cheng, Ann Thorsnes, Emily Stearns, Liz Maitral, and Dominic Agoro-Ombaka; and by Alex Crabb of Caster Communications.

Administrative support for Vulkan 1.0 was provided by Andrew Riegel, Elizabeth Riegel, Glenn Fredericks, Kathleen Mattson and Michelle Clark of Gold Standard Group.

Technical support was provided by James Riordon, webmaster of Khronos.or= g and OpenGL.org.

Version 1.1.82
Last updated 2018-04-05 09:46:33 MDT

=E6=90= =9C=E7=B4=A2

=E5=A4=8D=E5=88=B6

=E6= =94=B6=E8=97=8F
=E7=BF=BB=E8=AF=91
------MultipartBoundary--qLVjWd2mJZuVXpZ7T5d8aGIIY8W483Ad8cFONoagZS---- Content-Type: text/css Content-Transfer-Encoding: quoted-printable Content-Location: https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css @charset "utf-8"; @font-face { font-family: FontAwesome; src: url("../fonts/fontawesome-webfo= nt.eot?#iefix&v=3D4.6.3") format("embedded-opentype"), url("../fonts/fontaw= esome-webfont.woff2?v=3D4.6.3") format("woff2"), url("../fonts/fontawesome-= webfont.woff?v=3D4.6.3") format("woff"), url("../fonts/fontawesome-webfont.= ttf?v=3D4.6.3") format("truetype"), url("../fonts/fontawesome-webfont.svg?v= =3D4.6.3#fontawesomeregular") format("svg"); font-weight: normal; font-styl= e: normal; } .fa { display: inline-block; font-style: normal; font-variant: normal; font= -weight: normal; font-stretch: normal; line-height: 1; font-family: FontAwe= some; font-size: inherit; text-rendering: auto; -webkit-font-smoothing: ant= ialiased; } .fa-lg { font-size: 1.33333em; line-height: 0.75em; vertical-align: -15%; } .fa-2x { font-size: 2em; } .fa-3x { font-size: 3em; } .fa-4x { font-size: 4em; } .fa-5x { font-size: 5em; } .fa-fw { width: 1.28571em; text-align: center; } .fa-ul { padding-left: 0px; margin-left: 2.14286em; list-style-type: none; = } .fa-ul > li { position: relative; } .fa-li { position: absolute; left: -2.14286em; width: 2.14286em; top: 0.142= 857em; text-align: center; } .fa-li.fa-lg { left: -1.85714em; } .fa-border { padding: 0.2em 0.25em 0.15em; border: 0.08em solid rgb(238, 23= 8, 238); border-radius: 0.1em; } .fa-pull-left { float: left; } .fa-pull-right { float: right; } .fa.fa-pull-left { margin-right: 0.3em; } .fa.fa-pull-right { margin-left: 0.3em; } .pull-right { float: right; } .pull-left { float: left; } .fa.pull-left { margin-right: 0.3em; } .fa.pull-right { margin-left: 0.3em; } .fa-spin { animation: fa-spin 2s linear infinite; } .fa-pulse { animation: fa-spin 1s steps(8, end) infinite; } @-webkit-keyframes fa-spin {=20 0% { transform: rotate(0deg); } 100% { transform: rotate(359deg); } } @keyframes fa-spin {=20 0% { transform: rotate(0deg); } 100% { transform: rotate(359deg); } } .fa-rotate-90 { transform: rotate(90deg); } .fa-rotate-180 { transform: rotate(180deg); } .fa-rotate-270 { transform: rotate(270deg); } .fa-flip-horizontal { transform: scale(-1, 1); } .fa-flip-vertical { transform: scale(1, -1); } :root .fa-rotate-90, :root .fa-rotate-180, :root .fa-rotate-270, :root .fa-= flip-horizontal, :root .fa-flip-vertical { filter: none; } .fa-stack { position: relative; display: inline-block; width: 2em; height: = 2em; line-height: 2em; vertical-align: middle; } .fa-stack-1x, .fa-stack-2x { position: absolute; left: 0px; width: 100%; te= xt-align: center; } .fa-stack-1x { line-height: inherit; } .fa-stack-2x { font-size: 2em; } .fa-inverse { color: rgb(255, 255, 255); } .fa-glass::before { content: "=EF=80=80"; } .fa-music::before { content: "=EF=80=81"; } .fa-search::before { content: "=EF=80=82"; } .fa-envelope-o::before { content: "=EF=80=83"; } .fa-heart::before { content: "=EF=80=84"; } .fa-star::before { content: "=EF=80=85"; } .fa-star-o::before { content: "=EF=80=86"; } .fa-user::before { content: "=EF=80=87"; } .fa-film::before { content: "=EF=80=88"; } .fa-th-large::before { content: "=EF=80=89"; } .fa-th::before { content: "=EF=80=8A"; } .fa-th-list::before { content: "=EF=80=8B"; } .fa-check::before { content: "=EF=80=8C"; } .fa-remove::before, .fa-close::before, .fa-times::before { content: "=EF=80= =8D"; } .fa-search-plus::before { content: "=EF=80=8E"; } .fa-search-minus::before { content: "=EF=80=90"; } .fa-power-off::before { content: "=EF=80=91"; } .fa-signal::before { content: "=EF=80=92"; } .fa-gear::before, .fa-cog::before { content: "=EF=80=93"; } .fa-trash-o::before { content: "=EF=80=94"; } .fa-home::before { content: "=EF=80=95"; } .fa-file-o::before { content: "=EF=80=96"; } .fa-clock-o::before { content: "=EF=80=97"; } .fa-road::before { content: "=EF=80=98"; } .fa-download::before { content: "=EF=80=99"; } .fa-arrow-circle-o-down::before { content: "=EF=80=9A"; } .fa-arrow-circle-o-up::before { content: "=EF=80=9B"; } .fa-inbox::before { content: "=EF=80=9C"; } .fa-play-circle-o::before { content: "=EF=80=9D"; } .fa-rotate-right::before, .fa-repeat::before { content: "=EF=80=9E"; } .fa-refresh::before { content: "=EF=80=A1"; } .fa-list-alt::before { content: "=EF=80=A2"; } .fa-lock::before { content: "=EF=80=A3"; } .fa-flag::before { content: "=EF=80=A4"; } .fa-headphones::before { content: "=EF=80=A5"; } .fa-volume-off::before { content: "=EF=80=A6"; } .fa-volume-down::before { content: "=EF=80=A7"; } .fa-volume-up::before { content: "=EF=80=A8"; } .fa-qrcode::before { content: "=EF=80=A9"; } .fa-barcode::before { content: "=EF=80=AA"; } .fa-tag::before { content: "=EF=80=AB"; } .fa-tags::before { content: "=EF=80=AC"; } .fa-book::before { content: "=EF=80=AD"; } .fa-bookmark::before { content: "=EF=80=AE"; } .fa-print::before { content: "=EF=80=AF"; } .fa-camera::before { content: "=EF=80=B0"; } .fa-font::before { content: "=EF=80=B1"; } .fa-bold::before { content: "=EF=80=B2"; } .fa-italic::before { content: "=EF=80=B3"; } .fa-text-height::before { content: "=EF=80=B4"; } .fa-text-width::before { content: "=EF=80=B5"; } .fa-align-left::before { content: "=EF=80=B6"; } .fa-align-center::before { content: "=EF=80=B7"; } .fa-align-right::before { content: "=EF=80=B8"; } .fa-align-justify::before { content: "=EF=80=B9"; } .fa-list::before { content: "=EF=80=BA"; } .fa-dedent::before, .fa-outdent::before { content: "=EF=80=BB"; } .fa-indent::before { content: "=EF=80=BC"; } .fa-video-camera::before { content: "=EF=80=BD"; } .fa-photo::before, .fa-image::before, .fa-picture-o::before { content: "=EF= =80=BE"; } .fa-pencil::before { content: "=EF=81=80"; } .fa-map-marker::before { content: "=EF=81=81"; } .fa-adjust::before { content: "=EF=81=82"; } .fa-tint::before { content: "=EF=81=83"; } .fa-edit::before, .fa-pencil-square-o::before { content: "=EF=81=84"; } .fa-share-square-o::before { content: "=EF=81=85"; } .fa-check-square-o::before { content: "=EF=81=86"; } .fa-arrows::before { content: "=EF=81=87"; } .fa-step-backward::before { content: "=EF=81=88"; } .fa-fast-backward::before { content: "=EF=81=89"; } .fa-backward::before { content: "=EF=81=8A"; } .fa-play::before { content: "=EF=81=8B"; } .fa-pause::before { content: "=EF=81=8C"; } .fa-stop::before { content: "=EF=81=8D"; } .fa-forward::before { content: "=EF=81=8E"; } .fa-fast-forward::before { content: "=EF=81=90"; } .fa-step-forward::before { content: "=EF=81=91"; } .fa-eject::before { content: "=EF=81=92"; } .fa-chevron-left::before { content: "=EF=81=93"; } .fa-chevron-right::before { content: "=EF=81=94"; } .fa-plus-circle::before { content: "=EF=81=95"; } .fa-minus-circle::before { content: "=EF=81=96"; } .fa-times-circle::before { content: "=EF=81=97"; } .fa-check-circle::before { content: "=EF=81=98"; } .fa-question-circle::before { content: "=EF=81=99"; } .fa-info-circle::before { content: "=EF=81=9A"; } .fa-crosshairs::before { content: "=EF=81=9B"; } .fa-times-circle-o::before { content: "=EF=81=9C"; } .fa-check-circle-o::before { content: "=EF=81=9D"; } .fa-ban::before { content: "=EF=81=9E"; } .fa-arrow-left::before { content: "=EF=81=A0"; } .fa-arrow-right::before { content: "=EF=81=A1"; } .fa-arrow-up::before { content: "=EF=81=A2"; } .fa-arrow-down::before { content: "=EF=81=A3"; } .fa-mail-forward::before, .fa-share::before { content: "=EF=81=A4"; } .fa-expand::before { content: "=EF=81=A5"; } .fa-compress::before { content: "=EF=81=A6"; } .fa-plus::before { content: "=EF=81=A7"; } .fa-minus::before { content: "=EF=81=A8"; } .fa-asterisk::before { content: "=EF=81=A9"; } .fa-exclamation-circle::before { content: "=EF=81=AA"; } .fa-gift::before { content: "=EF=81=AB"; } .fa-leaf::before { content: "=EF=81=AC"; } .fa-fire::before { content: "=EF=81=AD"; } .fa-eye::before { content: "=EF=81=AE"; } .fa-eye-slash::before { content: "=EF=81=B0"; } .fa-warning::before, .fa-exclamation-triangle::before { content: "=EF=81=B1= "; } .fa-plane::before { content: "=EF=81=B2"; } .fa-calendar::before { content: "=EF=81=B3"; } .fa-random::before { content: "=EF=81=B4"; } .fa-comment::before { content: "=EF=81=B5"; } .fa-magnet::before { content: "=EF=81=B6"; } .fa-chevron-up::before { content: "=EF=81=B7"; } .fa-chevron-down::before { content: "=EF=81=B8"; } .fa-retweet::before { content: "=EF=81=B9"; } .fa-shopping-cart::before { content: "=EF=81=BA"; } .fa-folder::before { content: "=EF=81=BB"; } .fa-folder-open::before { content: "=EF=81=BC"; } .fa-arrows-v::before { content: "=EF=81=BD"; } .fa-arrows-h::before { content: "=EF=81=BE"; } .fa-bar-chart-o::before, .fa-bar-chart::before { content: "=EF=82=80"; } .fa-twitter-square::before { content: "=EF=82=81"; } .fa-facebook-square::before { content: "=EF=82=82"; } .fa-camera-retro::before { content: "=EF=82=83"; } .fa-key::before { content: "=EF=82=84"; } .fa-gears::before, .fa-cogs::before { content: "=EF=82=85"; } .fa-comments::before { content: "=EF=82=86"; } .fa-thumbs-o-up::before { content: "=EF=82=87"; } .fa-thumbs-o-down::before { content: "=EF=82=88"; } .fa-star-half::before { content: "=EF=82=89"; } .fa-heart-o::before { content: "=EF=82=8A"; } .fa-sign-out::before { content: "=EF=82=8B"; } .fa-linkedin-square::before { content: "=EF=82=8C"; } .fa-thumb-tack::before { content: "=EF=82=8D"; } .fa-external-link::before { content: "=EF=82=8E"; } .fa-sign-in::before { content: "=EF=82=90"; } .fa-trophy::before { content: "=EF=82=91"; } .fa-github-square::before { content: "=EF=82=92"; } .fa-upload::before { content: "=EF=82=93"; } .fa-lemon-o::before { content: "=EF=82=94"; } .fa-phone::before { content: "=EF=82=95"; } .fa-square-o::before { content: "=EF=82=96"; } .fa-bookmark-o::before { content: "=EF=82=97"; } .fa-phone-square::before { content: "=EF=82=98"; } .fa-twitter::before { content: "=EF=82=99"; } .fa-facebook-f::before, .fa-facebook::before { content: "=EF=82=9A"; } .fa-github::before { content: "=EF=82=9B"; } .fa-unlock::before { content: "=EF=82=9C"; } .fa-credit-card::before { content: "=EF=82=9D"; } .fa-feed::before, .fa-rss::before { content: "=EF=82=9E"; } .fa-hdd-o::before { content: "=EF=82=A0"; } .fa-bullhorn::before { content: "=EF=82=A1"; } .fa-bell::before { content: "=EF=83=B3"; } .fa-certificate::before { content: "=EF=82=A3"; } .fa-hand-o-right::before { content: "=EF=82=A4"; } .fa-hand-o-left::before { content: "=EF=82=A5"; } .fa-hand-o-up::before { content: "=EF=82=A6"; } .fa-hand-o-down::before { content: "=EF=82=A7"; } .fa-arrow-circle-left::before { content: "=EF=82=A8"; } .fa-arrow-circle-right::before { content: "=EF=82=A9"; } .fa-arrow-circle-up::before { content: "=EF=82=AA"; } .fa-arrow-circle-down::before { content: "=EF=82=AB"; } .fa-globe::before { content: "=EF=82=AC"; } .fa-wrench::before { content: "=EF=82=AD"; } .fa-tasks::before { content: "=EF=82=AE"; } .fa-filter::before { content: "=EF=82=B0"; } .fa-briefcase::before { content: "=EF=82=B1"; } .fa-arrows-alt::before { content: "=EF=82=B2"; } .fa-group::before, .fa-users::before { content: "=EF=83=80"; } .fa-chain::before, .fa-link::before { content: "=EF=83=81"; } .fa-cloud::before { content: "=EF=83=82"; } .fa-flask::before { content: "=EF=83=83"; } .fa-cut::before, .fa-scissors::before { content: "=EF=83=84"; } .fa-copy::before, .fa-files-o::before { content: "=EF=83=85"; } .fa-paperclip::before { content: "=EF=83=86"; } .fa-save::before, .fa-floppy-o::before { content: "=EF=83=87"; } .fa-square::before { content: "=EF=83=88"; } .fa-navicon::before, .fa-reorder::before, .fa-bars::before { content: "=EF= =83=89"; } .fa-list-ul::before { content: "=EF=83=8A"; } .fa-list-ol::before { content: "=EF=83=8B"; } .fa-strikethrough::before { content: "=EF=83=8C"; } .fa-underline::before { content: "=EF=83=8D"; } .fa-table::before { content: "=EF=83=8E"; } .fa-magic::before { content: "=EF=83=90"; } .fa-truck::before { content: "=EF=83=91"; } .fa-pinterest::before { content: "=EF=83=92"; } .fa-pinterest-square::before { content: "=EF=83=93"; } .fa-google-plus-square::before { content: "=EF=83=94"; } .fa-google-plus::before { content: "=EF=83=95"; } .fa-money::before { content: "=EF=83=96"; } .fa-caret-down::before { content: "=EF=83=97"; } .fa-caret-up::before { content: "=EF=83=98"; } .fa-caret-left::before { content: "=EF=83=99"; } .fa-caret-right::before { content: "=EF=83=9A"; } .fa-columns::before { content: "=EF=83=9B"; } .fa-unsorted::before, .fa-sort::before { content: "=EF=83=9C"; } .fa-sort-down::before, .fa-sort-desc::before { content: "=EF=83=9D"; } .fa-sort-up::before, .fa-sort-asc::before { content: "=EF=83=9E"; } .fa-envelope::before { content: "=EF=83=A0"; } .fa-linkedin::before { content: "=EF=83=A1"; } .fa-rotate-left::before, .fa-undo::before { content: "=EF=83=A2"; } .fa-legal::before, .fa-gavel::before { content: "=EF=83=A3"; } .fa-dashboard::before, .fa-tachometer::before { content: "=EF=83=A4"; } .fa-comment-o::before { content: "=EF=83=A5"; } .fa-comments-o::before { content: "=EF=83=A6"; } .fa-flash::before, .fa-bolt::before { content: "=EF=83=A7"; } .fa-sitemap::before { content: "=EF=83=A8"; } .fa-umbrella::before { content: "=EF=83=A9"; } .fa-paste::before, .fa-clipboard::before { content: "=EF=83=AA"; } .fa-lightbulb-o::before { content: "=EF=83=AB"; } .fa-exchange::before { content: "=EF=83=AC"; } .fa-cloud-download::before { content: "=EF=83=AD"; } .fa-cloud-upload::before { content: "=EF=83=AE"; } .fa-user-md::before { content: "=EF=83=B0"; } .fa-stethoscope::before { content: "=EF=83=B1"; } .fa-suitcase::before { content: "=EF=83=B2"; } .fa-bell-o::before { content: "=EF=82=A2"; } .fa-coffee::before { content: "=EF=83=B4"; } .fa-cutlery::before { content: "=EF=83=B5"; } .fa-file-text-o::before { content: "=EF=83=B6"; } .fa-building-o::before { content: "=EF=83=B7"; } .fa-hospital-o::before { content: "=EF=83=B8"; } .fa-ambulance::before { content: "=EF=83=B9"; } .fa-medkit::before { content: "=EF=83=BA"; } .fa-fighter-jet::before { content: "=EF=83=BB"; } .fa-beer::before { content: "=EF=83=BC"; } .fa-h-square::before { content: "=EF=83=BD"; } .fa-plus-square::before { content: "=EF=83=BE"; } .fa-angle-double-left::before { content: "=EF=84=80"; } .fa-angle-double-right::before { content: "=EF=84=81"; } .fa-angle-double-up::before { content: "=EF=84=82"; } .fa-angle-double-down::before { content: "=EF=84=83"; } .fa-angle-left::before { content: "=EF=84=84"; } .fa-angle-right::before { content: "=EF=84=85"; } .fa-angle-up::before { content: "=EF=84=86"; } .fa-angle-down::before { content: "=EF=84=87"; } .fa-desktop::before { content: "=EF=84=88"; } .fa-laptop::before { content: "=EF=84=89"; } .fa-tablet::before { content: "=EF=84=8A"; } .fa-mobile-phone::before, .fa-mobile::before { content: "=EF=84=8B"; } .fa-circle-o::before { content: "=EF=84=8C"; } .fa-quote-left::before { content: "=EF=84=8D"; } .fa-quote-right::before { content: "=EF=84=8E"; } .fa-spinner::before { content: "=EF=84=90"; } .fa-circle::before { content: "=EF=84=91"; } .fa-mail-reply::before, .fa-reply::before { content: "=EF=84=92"; } .fa-github-alt::before { content: "=EF=84=93"; } .fa-folder-o::before { content: "=EF=84=94"; } .fa-folder-open-o::before { content: "=EF=84=95"; } .fa-smile-o::before { content: "=EF=84=98"; } .fa-frown-o::before { content: "=EF=84=99"; } .fa-meh-o::before { content: "=EF=84=9A"; } .fa-gamepad::before { content: "=EF=84=9B"; } .fa-keyboard-o::before { content: "=EF=84=9C"; } .fa-flag-o::before { content: "=EF=84=9D"; } .fa-flag-checkered::before { content: "=EF=84=9E"; } .fa-terminal::before { content: "=EF=84=A0"; } .fa-code::before { content: "=EF=84=A1"; } .fa-mail-reply-all::before, .fa-reply-all::before { content: "=EF=84=A2"; } .fa-star-half-empty::before, .fa-star-half-full::before, .fa-star-half-o::b= efore { content: "=EF=84=A3"; } .fa-location-arrow::before { content: "=EF=84=A4"; } .fa-crop::before { content: "=EF=84=A5"; } .fa-code-fork::before { content: "=EF=84=A6"; } .fa-unlink::before, .fa-chain-broken::before { content: "=EF=84=A7"; } .fa-question::before { content: "=EF=84=A8"; } .fa-info::before { content: "=EF=84=A9"; } .fa-exclamation::before { content: "=EF=84=AA"; } .fa-superscript::before { content: "=EF=84=AB"; } .fa-subscript::before { content: "=EF=84=AC"; } .fa-eraser::before { content: "=EF=84=AD"; } .fa-puzzle-piece::before { content: "=EF=84=AE"; } .fa-microphone::before { content: "=EF=84=B0"; } .fa-microphone-slash::before { content: "=EF=84=B1"; } .fa-shield::before { content: "=EF=84=B2"; } .fa-calendar-o::before { content: "=EF=84=B3"; } .fa-fire-extinguisher::before { content: "=EF=84=B4"; } .fa-rocket::before { content: "=EF=84=B5"; } .fa-maxcdn::before { content: "=EF=84=B6"; } .fa-chevron-circle-left::before { content: "=EF=84=B7"; } .fa-chevron-circle-right::before { content: "=EF=84=B8"; } .fa-chevron-circle-up::before { content: "=EF=84=B9"; } .fa-chevron-circle-down::before { content: "=EF=84=BA"; } .fa-html5::before { content: "=EF=84=BB"; } .fa-css3::before { content: "=EF=84=BC"; } .fa-anchor::before { content: "=EF=84=BD"; } .fa-unlock-alt::before { content: "=EF=84=BE"; } .fa-bullseye::before { content: "=EF=85=80"; } .fa-ellipsis-h::before { content: "=EF=85=81"; } .fa-ellipsis-v::before { content: "=EF=85=82"; } .fa-rss-square::before { content: "=EF=85=83"; } .fa-play-circle::before { content: "=EF=85=84"; } .fa-ticket::before { content: "=EF=85=85"; } .fa-minus-square::before { content: "=EF=85=86"; } .fa-minus-square-o::before { content: "=EF=85=87"; } .fa-level-up::before { content: "=EF=85=88"; } .fa-level-down::before { content: "=EF=85=89"; } .fa-check-square::before { content: "=EF=85=8A"; } .fa-pencil-square::before { content: "=EF=85=8B"; } .fa-external-link-square::before { content: "=EF=85=8C"; } .fa-share-square::before { content: "=EF=85=8D"; } .fa-compass::before { content: "=EF=85=8E"; } .fa-toggle-down::before, .fa-caret-square-o-down::before { content: "=EF=85= =90"; } .fa-toggle-up::before, .fa-caret-square-o-up::before { content: "=EF=85=91"= ; } .fa-toggle-right::before, .fa-caret-square-o-right::before { content: "=EF= =85=92"; } .fa-euro::before, .fa-eur::before { content: "=EF=85=93"; } .fa-gbp::before { content: "=EF=85=94"; } .fa-dollar::before, .fa-usd::before { content: "=EF=85=95"; } .fa-rupee::before, .fa-inr::before { content: "=EF=85=96"; } .fa-cny::before, .fa-rmb::before, .fa-yen::before, .fa-jpy::before { conten= t: "=EF=85=97"; } .fa-ruble::before, .fa-rouble::before, .fa-rub::before { content: "=EF=85= =98"; } .fa-won::before, .fa-krw::before { content: "=EF=85=99"; } .fa-bitcoin::before, .fa-btc::before { content: "=EF=85=9A"; } .fa-file::before { content: "=EF=85=9B"; } .fa-file-text::before { content: "=EF=85=9C"; } .fa-sort-alpha-asc::before { content: "=EF=85=9D"; } .fa-sort-alpha-desc::before { content: "=EF=85=9E"; } .fa-sort-amount-asc::before { content: "=EF=85=A0"; } .fa-sort-amount-desc::before { content: "=EF=85=A1"; } .fa-sort-numeric-asc::before { content: "=EF=85=A2"; } .fa-sort-numeric-desc::before { content: "=EF=85=A3"; } .fa-thumbs-up::before { content: "=EF=85=A4"; } .fa-thumbs-down::before { content: "=EF=85=A5"; } .fa-youtube-square::before { content: "=EF=85=A6"; } .fa-youtube::before { content: "=EF=85=A7"; } .fa-xing::before { content: "=EF=85=A8"; } .fa-xing-square::before { content: "=EF=85=A9"; } .fa-youtube-play::before { content: "=EF=85=AA"; } .fa-dropbox::before { content: "=EF=85=AB"; } .fa-stack-overflow::before { content: "=EF=85=AC"; } .fa-instagram::before { content: "=EF=85=AD"; } .fa-flickr::before { content: "=EF=85=AE"; } .fa-adn::before { content: "=EF=85=B0"; } .fa-bitbucket::before { content: "=EF=85=B1"; } .fa-bitbucket-square::before { content: "=EF=85=B2"; } .fa-tumblr::before { content: "=EF=85=B3"; } .fa-tumblr-square::before { content: "=EF=85=B4"; } .fa-long-arrow-down::before { content: "=EF=85=B5"; } .fa-long-arrow-up::before { content: "=EF=85=B6"; } .fa-long-arrow-left::before { content: "=EF=85=B7"; } .fa-long-arrow-right::before { content: "=EF=85=B8"; } .fa-apple::before { content: "=EF=85=B9"; } .fa-windows::before { content: "=EF=85=BA"; } .fa-android::before { content: "=EF=85=BB"; } .fa-linux::before { content: "=EF=85=BC"; } .fa-dribbble::before { content: "=EF=85=BD"; } .fa-skype::before { content: "=EF=85=BE"; } .fa-foursquare::before { content: "=EF=86=80"; } .fa-trello::before { content: "=EF=86=81"; } .fa-female::before { content: "=EF=86=82"; } .fa-male::before { content: "=EF=86=83"; } .fa-gittip::before, .fa-gratipay::before { content: "=EF=86=84"; } .fa-sun-o::before { content: "=EF=86=85"; } .fa-moon-o::before { content: "=EF=86=86"; } .fa-archive::before { content: "=EF=86=87"; } .fa-bug::before { content: "=EF=86=88"; } .fa-vk::before { content: "=EF=86=89"; } .fa-weibo::before { content: "=EF=86=8A"; } .fa-renren::before { content: "=EF=86=8B"; } .fa-pagelines::before { content: "=EF=86=8C"; } .fa-stack-exchange::before { content: "=EF=86=8D"; } .fa-arrow-circle-o-right::before { content: "=EF=86=8E"; } .fa-arrow-circle-o-left::before { content: "=EF=86=90"; } .fa-toggle-left::before, .fa-caret-square-o-left::before { content: "=EF=86= =91"; } .fa-dot-circle-o::before { content: "=EF=86=92"; } .fa-wheelchair::before { content: "=EF=86=93"; } .fa-vimeo-square::before { content: "=EF=86=94"; } .fa-turkish-lira::before, .fa-try::before { content: "=EF=86=95"; } .fa-plus-square-o::before { content: "=EF=86=96"; } .fa-space-shuttle::before { content: "=EF=86=97"; } .fa-slack::before { content: "=EF=86=98"; } .fa-envelope-square::before { content: "=EF=86=99"; } .fa-wordpress::before { content: "=EF=86=9A"; } .fa-openid::before { content: "=EF=86=9B"; } .fa-institution::before, .fa-bank::before, .fa-university::before { content= : "=EF=86=9C"; } .fa-mortar-board::before, .fa-graduation-cap::before { content: "=EF=86=9D"= ; } .fa-yahoo::before { content: "=EF=86=9E"; } .fa-google::before { content: "=EF=86=A0"; } .fa-reddit::before { content: "=EF=86=A1"; } .fa-reddit-square::before { content: "=EF=86=A2"; } .fa-stumbleupon-circle::before { content: "=EF=86=A3"; } .fa-stumbleupon::before { content: "=EF=86=A4"; } .fa-delicious::before { content: "=EF=86=A5"; } .fa-digg::before { content: "=EF=86=A6"; } .fa-pied-piper-pp::before { content: "=EF=86=A7"; } .fa-pied-piper-alt::before { content: "=EF=86=A8"; } .fa-drupal::before { content: "=EF=86=A9"; } .fa-joomla::before { content: "=EF=86=AA"; } .fa-language::before { content: "=EF=86=AB"; } .fa-fax::before { content: "=EF=86=AC"; } .fa-building::before { content: "=EF=86=AD"; } .fa-child::before { content: "=EF=86=AE"; } .fa-paw::before { content: "=EF=86=B0"; } .fa-spoon::before { content: "=EF=86=B1"; } .fa-cube::before { content: "=EF=86=B2"; } .fa-cubes::before { content: "=EF=86=B3"; } .fa-behance::before { content: "=EF=86=B4"; } .fa-behance-square::before { content: "=EF=86=B5"; } .fa-steam::before { content: "=EF=86=B6"; } .fa-steam-square::before { content: "=EF=86=B7"; } .fa-recycle::before { content: "=EF=86=B8"; } .fa-automobile::before, .fa-car::before { content: "=EF=86=B9"; } .fa-cab::before, .fa-taxi::before { content: "=EF=86=BA"; } .fa-tree::before { content: "=EF=86=BB"; } .fa-spotify::before { content: "=EF=86=BC"; } .fa-deviantart::before { content: "=EF=86=BD"; } .fa-soundcloud::before { content: "=EF=86=BE"; } .fa-database::before { content: "=EF=87=80"; } .fa-file-pdf-o::before { content: "=EF=87=81"; } .fa-file-word-o::before { content: "=EF=87=82"; } .fa-file-excel-o::before { content: "=EF=87=83"; } .fa-file-powerpoint-o::before { content: "=EF=87=84"; } .fa-file-photo-o::before, .fa-file-picture-o::before, .fa-file-image-o::bef= ore { content: "=EF=87=85"; } .fa-file-zip-o::before, .fa-file-archive-o::before { content: "=EF=87=86"; = } .fa-file-sound-o::before, .fa-file-audio-o::before { content: "=EF=87=87"; = } .fa-file-movie-o::before, .fa-file-video-o::before { content: "=EF=87=88"; = } .fa-file-code-o::before { content: "=EF=87=89"; } .fa-vine::before { content: "=EF=87=8A"; } .fa-codepen::before { content: "=EF=87=8B"; } .fa-jsfiddle::before { content: "=EF=87=8C"; } .fa-life-bouy::before, .fa-life-buoy::before, .fa-life-saver::before, .fa-s= upport::before, .fa-life-ring::before { content: "=EF=87=8D"; } .fa-circle-o-notch::before { content: "=EF=87=8E"; } .fa-ra::before, .fa-resistance::before, .fa-rebel::before { content: "=EF= =87=90"; } .fa-ge::before, .fa-empire::before { content: "=EF=87=91"; } .fa-git-square::before { content: "=EF=87=92"; } .fa-git::before { content: "=EF=87=93"; } .fa-y-combinator-square::before, .fa-yc-square::before, .fa-hacker-news::be= fore { content: "=EF=87=94"; } .fa-tencent-weibo::before { content: "=EF=87=95"; } .fa-qq::before { content: "=EF=87=96"; } .fa-wechat::before, .fa-weixin::before { content: "=EF=87=97"; } .fa-send::before, .fa-paper-plane::before { content: "=EF=87=98"; } .fa-send-o::before, .fa-paper-plane-o::before { content: "=EF=87=99"; } .fa-history::before { content: "=EF=87=9A"; } .fa-circle-thin::before { content: "=EF=87=9B"; } .fa-header::before { content: "=EF=87=9C"; } .fa-paragraph::before { content: "=EF=87=9D"; } .fa-sliders::before { content: "=EF=87=9E"; } .fa-share-alt::before { content: "=EF=87=A0"; } .fa-share-alt-square::before { content: "=EF=87=A1"; } .fa-bomb::before { content: "=EF=87=A2"; } .fa-soccer-ball-o::before, .fa-futbol-o::before { content: "=EF=87=A3"; } .fa-tty::before { content: "=EF=87=A4"; } .fa-binoculars::before { content: "=EF=87=A5"; } .fa-plug::before { content: "=EF=87=A6"; } .fa-slideshare::before { content: "=EF=87=A7"; } .fa-twitch::before { content: "=EF=87=A8"; } .fa-yelp::before { content: "=EF=87=A9"; } .fa-newspaper-o::before { content: "=EF=87=AA"; } .fa-wifi::before { content: "=EF=87=AB"; } .fa-calculator::before { content: "=EF=87=AC"; } .fa-paypal::before { content: "=EF=87=AD"; } .fa-google-wallet::before { content: "=EF=87=AE"; } .fa-cc-visa::before { content: "=EF=87=B0"; } .fa-cc-mastercard::before { content: "=EF=87=B1"; } .fa-cc-discover::before { content: "=EF=87=B2"; } .fa-cc-amex::before { content: "=EF=87=B3"; } .fa-cc-paypal::before { content: "=EF=87=B4"; } .fa-cc-stripe::before { content: "=EF=87=B5"; } .fa-bell-slash::before { content: "=EF=87=B6"; } .fa-bell-slash-o::before { content: "=EF=87=B7"; } .fa-trash::before { content: "=EF=87=B8"; } .fa-copyright::before { content: "=EF=87=B9"; } .fa-at::before { content: "=EF=87=BA"; } .fa-eyedropper::before { content: "=EF=87=BB"; } .fa-paint-brush::before { content: "=EF=87=BC"; } .fa-birthday-cake::before { content: "=EF=87=BD"; } .fa-area-chart::before { content: "=EF=87=BE"; } .fa-pie-chart::before { content: "=EF=88=80"; } .fa-line-chart::before { content: "=EF=88=81"; } .fa-lastfm::before { content: "=EF=88=82"; } .fa-lastfm-square::before { content: "=EF=88=83"; } .fa-toggle-off::before { content: "=EF=88=84"; } .fa-toggle-on::before { content: "=EF=88=85"; } .fa-bicycle::before { content: "=EF=88=86"; } .fa-bus::before { content: "=EF=88=87"; } .fa-ioxhost::before { content: "=EF=88=88"; } .fa-angellist::before { content: "=EF=88=89"; } .fa-cc::before { content: "=EF=88=8A"; } .fa-shekel::before, .fa-sheqel::before, .fa-ils::before { content: "=EF=88= =8B"; } .fa-meanpath::before { content: "=EF=88=8C"; } .fa-buysellads::before { content: "=EF=88=8D"; } .fa-connectdevelop::before { content: "=EF=88=8E"; } .fa-dashcube::before { content: "=EF=88=90"; } .fa-forumbee::before { content: "=EF=88=91"; } .fa-leanpub::before { content: "=EF=88=92"; } .fa-sellsy::before { content: "=EF=88=93"; } .fa-shirtsinbulk::before { content: "=EF=88=94"; } .fa-simplybuilt::before { content: "=EF=88=95"; } .fa-skyatlas::before { content: "=EF=88=96"; } .fa-cart-plus::before { content: "=EF=88=97"; } .fa-cart-arrow-down::before { content: "=EF=88=98"; } .fa-diamond::before { content: "=EF=88=99"; } .fa-ship::before { content: "=EF=88=9A"; } .fa-user-secret::before { content: "=EF=88=9B"; } .fa-motorcycle::before { content: "=EF=88=9C"; } .fa-street-view::before { content: "=EF=88=9D"; } .fa-heartbeat::before { content: "=EF=88=9E"; } .fa-venus::before { content: "=EF=88=A1"; } .fa-mars::before { content: "=EF=88=A2"; } .fa-mercury::before { content: "=EF=88=A3"; } .fa-intersex::before, .fa-transgender::before { content: "=EF=88=A4"; } .fa-transgender-alt::before { content: "=EF=88=A5"; } .fa-venus-double::before { content: "=EF=88=A6"; } .fa-mars-double::before { content: "=EF=88=A7"; } .fa-venus-mars::before { content: "=EF=88=A8"; } .fa-mars-stroke::before { content: "=EF=88=A9"; } .fa-mars-stroke-v::before { content: "=EF=88=AA"; } .fa-mars-stroke-h::before { content: "=EF=88=AB"; } .fa-neuter::before { content: "=EF=88=AC"; } .fa-genderless::before { content: "=EF=88=AD"; } .fa-facebook-official::before { content: "=EF=88=B0"; } .fa-pinterest-p::before { content: "=EF=88=B1"; } .fa-whatsapp::before { content: "=EF=88=B2"; } .fa-server::before { content: "=EF=88=B3"; } .fa-user-plus::before { content: "=EF=88=B4"; } .fa-user-times::before { content: "=EF=88=B5"; } .fa-hotel::before, .fa-bed::before { content: "=EF=88=B6"; } .fa-viacoin::before { content: "=EF=88=B7"; } .fa-train::before { content: "=EF=88=B8"; } .fa-subway::before { content: "=EF=88=B9"; } .fa-medium::before { content: "=EF=88=BA"; } .fa-yc::before, .fa-y-combinator::before { content: "=EF=88=BB"; } .fa-optin-monster::before { content: "=EF=88=BC"; } .fa-opencart::before { content: "=EF=88=BD"; } .fa-expeditedssl::before { content: "=EF=88=BE"; } .fa-battery-4::before, .fa-battery-full::before { content: "=EF=89=80"; } .fa-battery-3::before, .fa-battery-three-quarters::before { content: "=EF= =89=81"; } .fa-battery-2::before, .fa-battery-half::before { content: "=EF=89=82"; } .fa-battery-1::before, .fa-battery-quarter::before { content: "=EF=89=83"; = } .fa-battery-0::before, .fa-battery-empty::before { content: "=EF=89=84"; } .fa-mouse-pointer::before { content: "=EF=89=85"; } .fa-i-cursor::before { content: "=EF=89=86"; } .fa-object-group::before { content: "=EF=89=87"; } .fa-object-ungroup::before { content: "=EF=89=88"; } .fa-sticky-note::before { content: "=EF=89=89"; } .fa-sticky-note-o::before { content: "=EF=89=8A"; } .fa-cc-jcb::before { content: "=EF=89=8B"; } .fa-cc-diners-club::before { content: "=EF=89=8C"; } .fa-clone::before { content: "=EF=89=8D"; } .fa-balance-scale::before { content: "=EF=89=8E"; } .fa-hourglass-o::before { content: "=EF=89=90"; } .fa-hourglass-1::before, .fa-hourglass-start::before { content: "=EF=89=91"= ; } .fa-hourglass-2::before, .fa-hourglass-half::before { content: "=EF=89=92";= } .fa-hourglass-3::before, .fa-hourglass-end::before { content: "=EF=89=93"; = } .fa-hourglass::before { content: "=EF=89=94"; } .fa-hand-grab-o::before, .fa-hand-rock-o::before { content: "=EF=89=95"; } .fa-hand-stop-o::before, .fa-hand-paper-o::before { content: "=EF=89=96"; } .fa-hand-scissors-o::before { content: "=EF=89=97"; } .fa-hand-lizard-o::before { content: "=EF=89=98"; } .fa-hand-spock-o::before { content: "=EF=89=99"; } .fa-hand-pointer-o::before { content: "=EF=89=9A"; } .fa-hand-peace-o::before { content: "=EF=89=9B"; } .fa-trademark::before { content: "=EF=89=9C"; } .fa-registered::before { content: "=EF=89=9D"; } .fa-creative-commons::before { content: "=EF=89=9E"; } .fa-gg::before { content: "=EF=89=A0"; } .fa-gg-circle::before { content: "=EF=89=A1"; } .fa-tripadvisor::before { content: "=EF=89=A2"; } .fa-odnoklassniki::before { content: "=EF=89=A3"; } .fa-odnoklassniki-square::before { content: "=EF=89=A4"; } .fa-get-pocket::before { content: "=EF=89=A5"; } .fa-wikipedia-w::before { content: "=EF=89=A6"; } .fa-safari::before { content: "=EF=89=A7"; } .fa-chrome::before { content: "=EF=89=A8"; } .fa-firefox::before { content: "=EF=89=A9"; } .fa-opera::before { content: "=EF=89=AA"; } .fa-internet-explorer::before { content: "=EF=89=AB"; } .fa-tv::before, .fa-television::before { content: "=EF=89=AC"; } .fa-contao::before { content: "=EF=89=AD"; } .fa-500px::before { content: "=EF=89=AE"; } .fa-amazon::before { content: "=EF=89=B0"; } .fa-calendar-plus-o::before { content: "=EF=89=B1"; } .fa-calendar-minus-o::before { content: "=EF=89=B2"; } .fa-calendar-times-o::before { content: "=EF=89=B3"; } .fa-calendar-check-o::before { content: "=EF=89=B4"; } .fa-industry::before { content: "=EF=89=B5"; } .fa-map-pin::before { content: "=EF=89=B6"; } .fa-map-signs::before { content: "=EF=89=B7"; } .fa-map-o::before { content: "=EF=89=B8"; } .fa-map::before { content: "=EF=89=B9"; } .fa-commenting::before { content: "=EF=89=BA"; } .fa-commenting-o::before { content: "=EF=89=BB"; } .fa-houzz::before { content: "=EF=89=BC"; } .fa-vimeo::before { content: "=EF=89=BD"; } .fa-black-tie::before { content: "=EF=89=BE"; } .fa-fonticons::before { content: "=EF=8A=80"; } .fa-reddit-alien::before { content: "=EF=8A=81"; } .fa-edge::before { content: "=EF=8A=82"; } .fa-credit-card-alt::before { content: "=EF=8A=83"; } .fa-codiepie::before { content: "=EF=8A=84"; } .fa-modx::before { content: "=EF=8A=85"; } .fa-fort-awesome::before { content: "=EF=8A=86"; } .fa-usb::before { content: "=EF=8A=87"; } .fa-product-hunt::before { content: "=EF=8A=88"; } .fa-mixcloud::before { content: "=EF=8A=89"; } .fa-scribd::before { content: "=EF=8A=8A"; } .fa-pause-circle::before { content: "=EF=8A=8B"; } .fa-pause-circle-o::before { content: "=EF=8A=8C"; } .fa-stop-circle::before { content: "=EF=8A=8D"; } .fa-stop-circle-o::before { content: "=EF=8A=8E"; } .fa-shopping-bag::before { content: "=EF=8A=90"; } .fa-shopping-basket::before { content: "=EF=8A=91"; } .fa-hashtag::before { content: "=EF=8A=92"; } .fa-bluetooth::before { content: "=EF=8A=93"; } .fa-bluetooth-b::before { content: "=EF=8A=94"; } .fa-percent::before { content: "=EF=8A=95"; } .fa-gitlab::before { content: "=EF=8A=96"; } .fa-wpbeginner::before { content: "=EF=8A=97"; } .fa-wpforms::before { content: "=EF=8A=98"; } .fa-envira::before { content: "=EF=8A=99"; } .fa-universal-access::before { content: "=EF=8A=9A"; } .fa-wheelchair-alt::before { content: "=EF=8A=9B"; } .fa-question-circle-o::before { content: "=EF=8A=9C"; } .fa-blind::before { content: "=EF=8A=9D"; } .fa-audio-description::before { content: "=EF=8A=9E"; } .fa-volume-control-phone::before { content: "=EF=8A=A0"; } .fa-braille::before { content: "=EF=8A=A1"; } .fa-assistive-listening-systems::before { content: "=EF=8A=A2"; } .fa-asl-interpreting::before, .fa-american-sign-language-interpreting::befo= re { content: "=EF=8A=A3"; } .fa-deafness::before, .fa-hard-of-hearing::before, .fa-deaf::before { conte= nt: "=EF=8A=A4"; } .fa-glide::before { content: "=EF=8A=A5"; } .fa-glide-g::before { content: "=EF=8A=A6"; } .fa-signing::before, .fa-sign-language::before { content: "=EF=8A=A7"; } .fa-low-vision::before { content: "=EF=8A=A8"; } .fa-viadeo::before { content: "=EF=8A=A9"; } .fa-viadeo-square::before { content: "=EF=8A=AA"; } .fa-snapchat::before { content: "=EF=8A=AB"; } .fa-snapchat-ghost::before { content: "=EF=8A=AC"; } .fa-snapchat-square::before { content: "=EF=8A=AD"; } .fa-pied-piper::before { content: "=EF=8A=AE"; } .fa-first-order::before { content: "=EF=8A=B0"; } .fa-yoast::before { content: "=EF=8A=B1"; } .fa-themeisle::before { content: "=EF=8A=B2"; } .fa-google-plus-circle::before, .fa-google-plus-official::before { content:= "=EF=8A=B3"; } .fa-fa::before, .fa-font-awesome::before { content: "=EF=8A=B4"; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0px; margi= n: -1px; overflow: hidden; clip: rect(0px 0px 0px 0px); border: 0px; } .sr-only-focusable:active, .sr-only-focusable:focus { position: static; wid= th: auto; height: auto; margin: 0px; overflow: visible; clip: auto; } ------MultipartBoundary--qLVjWd2mJZuVXpZ7T5d8aGIIY8W483Ad8cFONoagZS---- Content-Type: application/octet-stream Content-Transfer-Encoding: base64 Content-Location: https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/fonts/fontawesome-webfont.woff2?v=4.6.3 d09GMgABAAAAARjYAA4AAAACVMgAARh5AAQBiQAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGiAG YACGAhEICoi7UIbpSwE2AiQDlQALlRgABCAFhnwHskw/d2ViZgZbOOCRANZtO690BenN+tPV5+gA YzbC1psVlvA+vFOtOK57HIAZXT/7////Pz1pjKElgeYAUNXartqt+//PZjg1Sogwqrl1BA+ymGax sMllQq9c2OumAkW5bPv96P2BQXeY1jaEERxmsxFGwI6gMGybDcO2TYFgO2mWT9+eVRPL1LHma9m2 Ij3oy7IL68O6ipbykMEvNg/hL2VYDXGk1XZme13yLQNvLOk1yya/fZpM5ss6nBrGMB578GX+xqVW KjN+poKKyjFNaB1NNDo5akcV70ITD6uKFeZLr7f3WeiX2zJjET253kDHD1YqK57LPe2jZ7k735/1 JcpxLH+vc1lGum9q3/NE/n908vZ/33daMXTDU1yRr6RM4o2H/qT33Gso4/YCMUNL53qfWiHgaU1/ nu4eekiM2IaS5upEW2djTpykwtWpE6nF9kXbfgVqwlZE+Q1bFdIvnotURMj6ocu+5n8VqBAFPEDC ahljbMu0u9t9nHPdZzQThNdG6WaTRpvEOwTb7EiDCgFFEBGwUAEjSRW7MXv2HFixzZzTuemqXbXL cHORuoj+n+vS/pNeKKlTtp0uq72dkQNOwo8DrDFT/vDfnP3PJEDbmaRUAlzT1WsiRyIVIFYTWhLm Z2Y/k3v/jkSgmjhmgars+pHt9skVk5+eOfufuc9n4GkSXKuI1uXujiDbItmWdV4fK4T5ifwl5PnX da9TqorPmSHhSgRZNZp7a/qlarWpSrKdzBLzaaDB8Mkhf4R06yK9val22RD6Q5QMMBuW4XCal2Fz lpxnCjOzf77/qX4zL4szuzxzr8CxCwJLsp20dQiLdK9uEpccFx7l5XRTsHx/pF2WfoEMSSog2wED SbIDDqDjATd5sOFFTEDwlkIVJROS/d9UVFT1enVcmd3fGOtlYqRiTQsuLWb0P9n7+AAgCE9zJC8u WaMdoLl1C6I3GANGjVE12EYN2K2KFdvojdyIHNEbJaW0CqICoqJiYKMY2G/Vq/8G2m/U+62PYxyA DnQD3UA30Cobe0hLqcLFUBSBORa+KNUqW+WV+iYmtqp78OLDV8gwZZnAuNuilDjzgXbFaLJhEd+f LbTIJZ4v9uN3Z2effJNcRaN4wl47SPodi0SmkyjVSiaitQOR6vJEwm1vfRMJMPK3aaMer2cj2Gl7 0ogM6OY0mDNm45M7lm23GfvM1vzAdntHYlDP4w5U2BMjYGC7sXckQmDdWKiJ9ZvgMYCAG2Mcs5AS /7+pVp8CFNHNMc5onQuidmt8uhtlePe9quJ7rx7AqgJIVhVAEQCpFgBSUhWIFgGQMwWQ1IJFUktR PXPYbK+e3aPpdWqtm/FAgVITlNRLUGojjTXZbubsN84G2WY/m8n2bJr+IPpBHv//v3TWbwWTsN2T wy6lxao9OW9DXqzuq1JJVQpQkhCoJMsIcJCwGZeEQwmHkYSMQU5K0CK0D+2eme/JOPyQXwloSuBQ hY2nxCSJSWIidMQTQ979xeYve+nl3yz/MoXVnL9e/eUyRR7Cvc7mv7/aqmos2mBk7thhh7EVQoGD CHcgfxYgBC2wMJHEU4owIYwsDdms6b1JDdgcMdnfp2ogaxM/vKiLLwRzsiqrskLI+PhfUG8v25sr /mkyu9eCIibESU678HN0/jdVJYhdK5tEGPr79b8j7bNuNrVyPAeDEaWkkNcw47H7dQ+Zy+L4b/d3 Ut9SRUVB5RUXM5Bxl1yC2hhaCVzpLyNODEvKt2HMlWh2500Ld2GgYFrZXGdmTvz/hAAB8ObRt7wD 8Mbco+oB3lt27MHJaysD+gMgEQh5GwIdXQ8oO0u0YdD6D3o0sDX8xsqVIH7H3ZVbL16xkpDgeywp YHcAP0qWB5FQXgzaaP+Gmv/fYBBaFIBVhBjGEKCSuDQytsgMMI2D5mGc2iG1+eH/fQZBPAkQU85N PMAjvM3i8BiGIcabILX13uQDbvNtl8cnKIovIebau6kH2nb58B2Ki4C3F78XCeABCBBhtBHzEAmD DUxCrHhBoYyzzdiHTBxuEQp5BIZUWm3FPTT5P7DJMZ2YHdyJZlFPXj6Zf/Tj0X+Pjt6TvkSPOQ7g MUMHB4sWDWoQVsBAprS322m36qos8ixN4maj22m3mo16rRp1pbcJ8s3iDgnLuEkh1Va/kRwW3/R3 f4U82983NZmiAUx+OjQpkaakr0vejgAzA/z/wSNj4av25AUq/qGXXNynJSqUSorRZF6OnQUKhcQg scPTCom2XOVyP5+UTWtKyOYcEPJJWqLvX+ZjuFhyaeKmWMbRYC6kkwFJZc+wnCtUtbAqKgTl02ZF jWRxE5o9OjI6GYJnljIoWO6XcFVGKpL7OlzcEqLCkWrCo8hFGhKmpOhaaKRCzuWoToK4Z4XikAAQ hBCmLdWU8rhc3ntYiWs+uEQvRKENFNkGzRDhgJRxJU+DWh7Q5RLogOCGuIxJ5poIupKWirDwMoMW JoBLl1BcnjbYijD3E3RsSwZdHffEHBJ4qvNIExfIZIpEAcIMTfsYinRpl1ANXStQeFi8FLdTLjyv yJFx8wxKbtUhZLvwTBEBXW4VJDKaOKQo0T+B5aWkOnlkKaGSYorwyugIk81KBoKcW0rTGkW/kDaM kIlrCD/NkMy5J5bb/5Aiwxc4uOL9GfDwSPCLIhM3bJJ8TxtzEwiEUDSISoSWT+4GwtyTZhKasJxB +CYpj4BkSmAJXW66FZdoCGlbsxOi6gaW+w+BqVOrKPoUsRBb8U9+GN4b9hzmGyw2Zj0y2HGzGPkA NY7lVuMfTU/C0a6tzpxIc8Xc+QMRPlp2YOxmu4k3i30zvWZtyFi/JvFjCw1xx7/t/PvAgjLecWB+ uevuHum/+eYGeI4ja0CXiTBYOq/5JDH78wv33LAPgvkchf0gcC4KZC9ecCJLyMVFFHEiJsNqtd6c evbpRNwJmjLLTrpHEBvAIKYNmuaaGIN2xnb7yGFEdl/XaWI+cXY2jkQp0SW2YGLS6K7YmO+eeGI6 5ttLvrtuF4sjT9JBNjvvj7R+jHmvSfommL2/un4L0IsXcOXeZ9byRtIJxhBx6JlhuvNUyt0rfHb9 EN9YodvEKNhR/g9DLgMRAejITteXmpG54fV66r3hF0tqm45KldlTNMCC/UBmMLAc8DOmi+/wcgK3 zPj21dd7QZQCA/ENrW33fCTpb39PHem9zSY3Ha8/sI+ZDKqv/c08hD7/WvLbzC+QKY3smNszZ3UG 0Vxeq30MnHE8jEk+4KO6iYhwvA1GQJgBlqbIGqZhVq9lkdOO4dC7phscM8T0CY9nD7UAYWb3abrk S3OQs7spH2ZKXfNqfVOJzHuREqdLzPVvtptI9uedyEOsewIiP8/TzAncTQJ+I3LW0iS3bAB4f7fb onfQJjEImKAoQxWqxddPffvkC3yZEY329k27DDZBMPMwaBtDAFjt8rBs89AuBU+rjiZl2yx5XjQW 19cOHASEDYxTUuVFFF29PuTBrLTkYg9iltt2ic0IzxKHjf/np5h3Zabb/2kU3X+rSWsSL0+OsU8A XPHEneCRfFvi2fQ/OKScbGdWxW8FkQkiqhUAFulWEc/PZwk7Rv0uIYzpI2yANiuCKY82sc6yPWDM GZaNjF0ireJemYxBgT8fAZWa7tN9vzyclsO61AutIlbLAA+28KTJD4yyoxyRJ773E0o7zS0qrV1K bMVn7c6UdTWOmg0f35gdb7ruQGw1M3JPpLxXMnj/0Kx1vj+szh5NmpzpmQ5faC43XHdn1uqidTe7 tnl7HlCIn7V4kNTnakU2Prhc/NbfFVWx00EAZ0cSja3Zn1guGPa/5JJL3yzn6a2D/NO+iiCTY5rQ DFUpUiVYQRgMlBzA1FQbszCyPSViM3Ol1m2T62ZiuuCZiiYMxm7IWVeZzmidg3M2xbDo2rLrq+oY uTa0cb58KaAypcEr6+QPOxOazzcyKmYH81mocuTJpquo5hlEdpJjh5HgeAqp3otJfbB/GuNJU0l2 0cPXHwGwFhWl9oIZMsomMkv98tm839Iw4NxBabzBlU6SlNF88YiUSjKGUaYsc2PymZspfScJiU6p LSoXnIV7n/TMe09FUooUUfPKGxnRY9evw94F7uOed/wEP8u/8cNpoYsXc/F/NRV5jB+RKE4LbF/f t+30Y5hycNzwftOymSnPpG6HqVVahEBFLvsX5cwUJjdFmT9azeCqXIcHxEoPsp685RDXYrK72gqm dDzeGCwp0cxKUYUWaVrZT2yv1AV7fzaepVKZfBZwjGeOrg4PK+dX2yeeub7ZkYbpbuNwZlbA2RlW r/wgnGXGSMlbYx7mc0bbvZ6XnwCSyyo0Jbs3RiP6w2n1feg3d2UEKIKAGE25Ew4FozddT2oaDTMr ffyzI1KktqSpOrMXxptLQ2RMWDVgSPnhVzbYta0131fCBCuXBN+VImWk15QSSzSbtWFNqU5JaCB2 u04pjMMFA06JGucQc1vXKvNl4FG/2tSOC0Z8ya6pm+a5l+2lKd1zCK894W7fzaFGpGFeJR3eks/e wvFik1JS5wouCpF1a/yHQWTntPU0aNSy6c3A2K0jPZprwTk0+HqogUvp9P0Qs5O48vi0udGyqQia Cp89ICq9+2D4pHiDO13hcKylVCyPLvqXwh6XEW5PcRV3TDSwYJPhOEQQLXnR3LC18Ufs6SeaLDEv Jg+r/rWOHlsqxFH5bVCRjkuhlS8CuuR06dLEJTpCnr12eS5Dy+fKbEzVf+UFXjgZ3p+vnuqTrF4K C8YLzbVtulwZhhejeMRxWxMRChQRXcODFcQyhBpLWSfzcjw2E2mPDN1U6eFoeDAZjg+FtISLfUH5 hgdoLskhaix0Qvi3z1PpUROw4T7T1ZH7ORBbw8GNVffPC3SHh3CHRt++oEbw64t6Kj8rKmlku6+/ akM+CnfhFOrv6G/W4gn6Rzdg2Osk+xvY3DItvPRXuKM31jKCkxq1YVFLqkqfJzLcydiQ/P6Kekmh cgQ0wl6UaoV8uB3xJEcNhW7woqcS7uglnvbrS4eaViLpjETuBoEb3uAqOF7HJRDB589dWsUpiC7e mvvQeXdFx0Zdolz0llzna6ZYs9DI2H32GEKsiXUzskVG3uyyLGhw42QIpFrOI8lZsscHR1Kkq795 0Rc9kTaS7a83/ZgmqL0QGjJskoDZtqucBskkI1TQaqcoLKBFn5lbrYCc71ttZxBqWdbMP4VYGprL qPj0mmviOWhGUlG4vkGXlHE6KLzZgrmjyW1D9y+IFFjl3GpIU2be1qLD1/bhhnrRDqTwyJmhvmAy UAI9ki2/KJJ8rK2Jz01JL5K0MM+DQS6ZPjuHslSB8nWYXALeeowagJASdDg5QhSmIJZRO4fcwKwK 1rHJ0Wyvk5W/gWuXCuJVwKfXlBQLbOqHZqpnWENFufalG97t7wPGjGrtBwjb9/zzTYqaGd31rMzW oIzcF0nY6OVwcOFLF3VcSdsso3zpKoCUcOchnnPKs7icibh6tcLT1uzcY14LzwVrkbv7ZJevcOEU WOKXQs/iIC+9NNXavd2p1poZXCSnaMs1UJpNlyRIOPcj9nJBNVCb2C/fH2UDJv48WEDpT4Ta/kal eYQm6c3QuwQHcSW6udGLkmCsj9Q6X9V4u+d2l6/Rka9k7ZwjQHak80Cb/rJ8656j8lbhJpvtO6Z9 WBEyYSg4qKTkasc6RlNExEjo+1Dd5ri9qVNLXl5M4x0BGmniciOCJ5EGy4HySom+sB4aYoVFCMj+ /Uo6jq0itS+Iai0Q7gtEBjEGLRbkPtzgyuJTEql+Jse0Xu4FMkyjJaRq4eZqAe5heAmFeEm5b2zM 3Ll4HkOGAClbdAgi7HVCwcjqdTu3/rqm4ryDBeC71UxXew8QmrVJRPWsQJhvwxrjZmI0No/o8Lpl djIBzjcvBHqfwmBZqLh0roPFArWsdTdxL+S17ns1tWhfh6jMzo6GRmZmytD/IRSViKiPSb5/GVvu V2jrM6L22pr7VLygrm/RC4GoWNvM8kpgfsBA2P0bnnnbspZKho/ld4TVQuaEdft2oAADLGhBcNqP GvBrRWgoc2V2uo3H3Zq4gLj95CWBHCoPYtOJiwFqt49rxpu+DPFmkHgvmldZZpbZzRKqzhtSebpa psJw71HAB1U+enhlQ20j/wA+OjRamZ10hlZUAYtlRNSuhFglHflSjlNuXuolqcvuivp+nkYdhWoE 7+bknUsLaLHz9RXEzalc7eRaPoWrO91Ux2VG1uVmyH+T1VcpEzfohsKXCVcKSejHKAeI2zLOeLI8 lSDOynwqz9FIAuHWjvQWxaW4Af7LK8Lzq6HCeU61QQ3jurz4+HrO7v029WlERvgE3zBFq9w5ASTB syD823qvBecLiUTdD4QwruHZFaR04TzQpwDL9Y5j6MdBSQ+sgn9aDJlRh8soYwDHlzDPBZ+XaS5v gfRiLpt4ZijfJxSCj3awiUXdhdiOylVLhJC7oR/sPaAvTvJAUYyhtpmzw6/+km9euWjK8RIb6mor xp+osPpCf/9hIv7ICOq489VV/Q0qEIqDHnNM5YdllVrUGsVRQT8ipwTBZhV5Of8hxRrWGVo4V70h 9cN3De9WKb/omPaziu7G4vl4FlEEdakocn/xksnr8Ia6eS35gEg4GHkZ2mYesjOrcJNzO0LptMJQ 2KEK25NrNr/B/nh3gS/5MOfwxsUeQvU2NG1pF/PJ+CCNUpqGkNb86Dni+BxmfGVixtkMtpLrT54Q pgdDQ3CyA8H+JOLVyVlXK+Tjy1NTVCmvCfYQlM6YhjABgj5b5drn8IpdbmQKzQvHjQx3ZYx0d9Kv eZWz2KxP5SrQUNlbyyrQF4isQnUtfUFrWQWwvAbKA0gBi4obmVYzw15U9o/KiMyFHlbRJK7XmRvt xrQ3ZYx++hsLpYvb6DymMgE25PHl0I3Taf7bPz8eXLiyzoO/MulnJsAgYRwiGSEAljrK/clMQBq7 FaTwZaxtkIJ3crtaZvxycDJ/TAlpe3CTl2maUw89DHgdbGTkhI2FSeFYtUomQaRW1u3eG13GMLjU lOVrMhKVIOWUKmvt/79S5Y6WfOmdhorbxUk68quUFsl3iKvmfRtDo+XtJDanfp+Pf5QcySF6IKOa 9aYv1p87gEuAQxwkyO+q3HUfd1a7Es3bbg0a/kQTnUUHgRJsZPQufek0uOzZsDzJZJUcIfSF3kuw aLUrI5fWTckSzeBjSR2aCkhaI5MzVwOHVEJCUFHokhqIlii3kUgVc8gDDa5x4nTaObDYrKFBV7r8 UFKsxkYR7ttDNWBRIcKjC6GhbGVfM1OZCV0+68xWg2aWLfRXv14YB0VWyDH1Rv7PVfCcoLR7R5sj VHS+ZdMjvuCS4oileCjEgmiNAdt9K80TzWSW6XRgTKVC2bpA2TlzJD24qaQ0pFOIkWnwi0ZPohDl punqKEtzRLKUViJRAsPEE8KkufFwUiPpOvpT7+/wvAi34fadLcRW8M4G4IHvbGL5sG87TrYVbk1s MFJfcovRtswSj6YQwKMk42NPVHcoeCDFUnXbuoHp8NzGOzrwLxjidFt7dvn3NpkELWxiGU8swBgq fn0ZLPvnaMJiy9MxMcJog6yNNGsTDE+OgZttlMvUDnhRkIKG4ijxD02tdJCDnBITkLCCNm9gIRW/ gUcofB0NErAqOXVqTgyyF8L04kZatucfUUlsOzz6qiE0i5gjJC0FV+xUW7yP6RE5dQJixyjzQx9W L3PzJPgW0KXQjjTl7TO6BGEqmT5x0YzmSnVZRpwx6wv3hpUTwYHxkYRxDJZk3uFIdpfRMoxs7TpM 00H0XER0d0B/GGxj6UHlFQzj4T+FZAfF5F/hSDAIaXqBXmH0yuD4bzLsRYla5Wk2874Urn3rt6r/ xYG1UjTYgNwbT/opKh0reGnEzZeCxeRLZ3h+h9eCSdY67LsB7dKeO8VaNC3b4sMGHorvk0P+Ems1 rwmi8P7o4H8dj7SVn6c35vft9hR2ViQEXFijQhvTlKBEIOz0hzXbZw8513XvzEe+2aFn29wtl4sg V2oCbSu4eOGzVDrE2wL3alI0QoVriH+ryY/WHqy2rJF3jxxyNbHYroR+Jgjn9TThTNnLvgIgpJ3D EK5zR9PK+5uM3cIbEw8sIzeWR+JuEz6yv08ZEePC8Pf1y69ppYRE4rGdYDIeTn7JXyGisxI5709S /T9qxeJ/Lovp0Bq98l9L/DDGgUJu9OCrJ1ePS8TbbKKo+Vmgrgzjy+iVdA2o/3SxctOlaUr3uoyl J257a68wESNnTpNSCSyBO7V+a6z/xNGXvbq1cblqjqvV13Y4bT5eq65qBnYWHUCEOpRUAhbJ/xEf KAhtykiZ4vtEOuW2oQextjwo1aLbPLcPZ5ElgJP7ZT76qzmA6pf6L+vRJScD+tVI9BFtPqASbPqE mDSKYez/JbOezLM75p55ZCZn12o5dZxPAI2IlbX4f0PMVZ5N36id1cSXN5F7yLnb6xYMtUGJhbpy a0K/6L3BKmWbOUgkal7lp399e+paVFEMadKxlWG7PKaPvNBUlPU9zocm5ZT1ruvzDUuA7yjATYGn 8DlJwIkRPohdWRRiEw3qwtl0KAQHRbYOYWebRrJIr/WgRnXtQ66FsvISrdZllVEQo85gzGwqGART 2mTtXyVNsbrvpLrsnCNzFmjbOosTmiiczkycVMes+ZxRzqXUB+gUAZijmCQqVpoHs1arLXHl0r/c ixhr0tctnfnCSaNOxhIhLx2OpYrpV5ajmipSk6Jq+c0qVuo5atQ+RrtU4URZVTKRGzszPaoE1Zgn mZaCKVLq0aqMmAX05dcMy3kF0TXHudgRHvLEFkN5bqBHLYzxyf338QKlCO60Do8nVBYUFFZRlv0/ WOmyI9Xdv3LDjplvhxnVfgiPBEE1jAn1aLOxk2BFvIi0ryGJ3G0xOjpYIao5U68rADbBv+Y9uZkS GLeS81AlSczq9RHmYFLKvxS9DMF1Nw/Zfzjy57XjLx1vuzip8kIar3JLfl6Oh6Nc5kw3j5eWtoKS m5fi4YCwzCk3uL42rFZo9UAuy7IrYVeBsatMy6bwzij7sAdfe0zFs+oRp94ykM/Nr53WtMq/i2mn pIelxRZfKI3NQomvUpU3MqOjduaMlIHt3nAZKw4Pp2qUOijnl8sqtxqVEGS//ybVXUnB0xKsMchh eoJk592jIG8y3d7QyPwvbly5MoU8JB7Ppfs0lTQYwlaXvuqXME4cKqSrTQBa8VeV85FUYJCmdcHl HkM/25Z2y2Us3oZoJ2vIAwKeKC+fhHivfYAUj3evkansWHBqraZrtYVf3nTKqot8s3yBTFw4rQwj PnaZsNMMXRIeq74mVKsTYswwNWa8Ucvv2Zukys5FmqYnvgaCmlaSnmj9A4fTT4xWBrOdhedEzzPo ppLJaOnGuAQ8b2OoLY86kIvBDBeWghQqhzaIic3AdgHTS7tpdxosPbZ0glCzAcfP/V+Y/fQyFbgf lhMv+11ZWFiRypeMs6rRKyL3tihm5PBGLuC9QnDfbeYTPtoXj1i7PFM9aW4B2N1k2ItGpKkDo6F+ UTlnaarH8m3MpDOZxLslcdNhBr08L1lIly7LX1Y4C8uVqaymrdS35diVgxcqvEkcadsNSds1s/nZ 7eqLqGYx0AkgUDvEFUYIpR3btMp3w3kPjyvsUehg1ngIMfgyy2IWDnmGyB6Q73m1ANFMsmcujNvm 17MvLD/UWovTkYJ62neraXd/f96o87K33w/t47OyTK5/wUSYeXKnvnN3YUjOrRd62mEJFh52U/Pr su6dTaqdkpDDVhIspK7cND2RXUoPQkgMG0PUQxaZ3itY/yvjCPP+UnsIfTmzIN0VfxIG00RMCFh1 Q984DJmvRzHbpVKxFJ3gymWZnL4V4eKjnxmXEmq5bQUT3zpzFMLQB+qo3WhVL/LTWXQ4BVzX09F2 iw1TCZxOx3JYy3aupj4YrV6AMplFTUPBWVsnuNj4Dd+2sZvCpA46oDqFif1fY+V8WZ2E+XheUQUa TCcAonHtOka6rJheWpXjiK+sMmQgBSpOeAnRHjD5brluwcw0IxgFtaPpGE1D10FdRLvQhgy2Mb8r wJBxXtcWlc4dLa18j5noBopQGyVdBuW9BLnHKuW6Tb51W729khY11vwRFWTsoikVfM735mDXBa0y FhZrW1fLH8lFYzHaV13IevXEFYCKRxtvvOhSyyRveTqm2LQ/sC1ZevM0rLdNOqnhOXKAO//6BSNV sH1xJzkm8gijlDob04EexHSdLoxtybxY+nUuuQKbPHzMnwla0K/4N3/Oniq2NrBSW0eorNWhOV8b x205JCOv+m6KLice+/5qpXBF9UlGbu+ZLrtGptCs922fNQ0PeI3Dgcl+evdCw5gbdp4tJHqAy0/7 9/47GjZNstMzV1tmmdlcEmeMsXXWNPQy5adf5Dl6U/pHr++vq+zjFwkDnN5ifvE3oM86+iAn8DzD DuxX/aaFHLdkCWK5lnQWaz0ekSTgYbNpvBPAidbGegR+CJMji8AXZrkZgUVvqwWjdZ1TPozY0xsA rtNeB/F1VjwQs0urAa7TbAIwYaKVN/qQzHXu5OnHWmqTlitMVIq3DTjwRJlLJS/e+bqMT6NcqNgh UVH1jrK8fXuKaHdYG2Su7AJ6MXttLSOrqO0lM6Q6omgV+c3TaPMQSMvKMeDdRpCXFU7HJC0VUj9m zJhJaHLgKWW/VkwrLFpu3rbQlZs3Iesqp6VEZTkqHV8tWUdER0kEK18kPF/Kj0oYan9x8lBF7zif 4bJKdjXBSXeTJtAKlqF02Q7xsqIO18Tk5K1M9Ff9W4RqPXaoTnIM+O0O2KrCsukrzYSIg5VjcEq1 WHyk4vDtw7fF6T6s95taThUSTwtW+JHLRL/iatxhsiFKkT/5WnF6aspWPCd5XUaNZRbToHwldKkj S6abRio3aAQ9MNnUYiHPI4PcuGVaoalXntJjoRCKNg1DCHmLNP4p2vNTSCSuxbHWDUONXHynaOpE kgJPOsvT93X6gyxJkrwyFw3qjr2wisoL6mtJXHGJF48qLJ7+RT9Rv004GkWbKCUAKMqeeFyxB/G8 whYdJJYCH6NAaWj2Wac0TMcQKSslpUbY+lonqpaB+KMeQe+rPNPaWA6vMwq1Mdb0UlaMtksrOcLz St3F8ikMxg6bUpKaliL+eerqz2XfTJXTwpiLG2lC7dUVOkApc1QIJcwnkyOCxYjqVinhm5rUQVHb qblkkPSRYZVsC6C53w4DlJRILorWOUSr3FFKm+b/UVgai5RNIZXCIA+6jl4qIgWVD9OOu5osBrbh KimpHL7a4XF6mogdUFZIXnGj4FmpHPrKxUnFUng6wWlgfMeUmzyUiJ2ozNuh9SSlqpdWi7480EQ1 UGbORCau9HswN5BAUEFtK3k1F4+jJyKiClPFa9FEqJGyj3L02sdgvGifd9V6tWwNWnOlBjOjaOfB itIWhIowL0lYRmHRaBs6WB6uj1BmnCEF6v7IQ1sc0t2BKS4lYUj+3fVBYIWKt9AgGTTiobQS3Z+p F6pL55izJ4KgsvUdxFq1FJia61LUrhmaHGrBtD5Fr4wNU/a+Fa8NjE7cgIZCgQny+XAOc8bWEgoV 0xPJpR5NYHkIMqmkm22TI35zy7rHmKICGwaZ/tP2mVQrmUZp4ZUwJH1rVDACVx+krr8iYxwILB+U R/TSMkJALfWJ0BjNdDJNdTNQKHM3sEGQfizCPPuKrxq8k+1vAj1GcMoAcBmTKhejSNf/H0zDNgMp DAMdbZ/E5rmiRDQIuCMQsw8wpIBCTcVu+6EgutNl0n9CSMevYeC93iHYgz0LvUsfMiUGYtuDXK07 KcqIjqrmGCDkbJPQ2eaU1DYzxrXPXDkvGHFObnFrJfCJJyiFxw1YtMrJeslcFkIRbr3AuaT6QNvN l+6uIPSmi1g/gabbMoAe64JVEI6iI0b02mGbpY9ncYbUaVwxqyFGqkojVCq0IM5mL6Ga0tMWgqdr N7t+jasjhzXp5FIscgK3IEX/2HjK1k/QGk8qJ7mLkX1hFGC9d7JFJdM8ySAj9SKq9e4JuYIhILNL 7oSSYjMIH2SuJ5w84TWFG6Ero9pGB3pWh22dbHLZ8WTad8XdviMW9n4ee+dqHvk1tIvy7htxefwM 1SyE9j4ur9eYnpF1Lq7oMegxlLwadf51jDLiTrSg3EfZMtOGhP+p6jMUkJPYcGUrwnaQsjDHg7KW 17r0+o7um9Hp0nsL9Fu3JYT61TOqX+BVxNFk77aA4CR/YnbnBa3b5dEtF4NEdUOlljea6Vn+XefV TRdfvUtl6B3XMfxr5rKC3vQX5fn+KvLu0JuNRwlbCTAADpqSXz3kW3J/y2Xf9bqlHLuJt6jqS52g H9vxWL59YjmD3SkcqKGvk0zUikyZ+i7i5LzTmvbIKlTX95izRGcrXFkF39Fna+kLOqmoDbPy67JX z1NplPijtzKj6Qw7F4FjEACEME7uI9nISfFHMxd7aWZ1mgAC/p9tozbaZDY6Fp1A0jDeOt2PxSfi eZBv4OSOroYpH1Vx+xKNBQ6SVreo5Wljih3CTRfE9DGX86qdD6llL8GpXNEySk4j4EGaeyYs+CJY mJOStIWxLiFxa0GODCidYq/FDoRFhtXVNQcErRybD4GHO8OA+Yv3F+q2AQEFChKkF9ms3JVVhvYB HWSd9IKWs3tBAGqXmAYKBAQCEjzxz4MSo/iy3Q7w72vw54YATnV7gScNShbtQa5/w4TfvyBzW2Cz g8Uo4vFafzKqN5yetXK8dYrsUWQWjLdWrgq7VqmWbcncrlBbS9gA4+1vLSUzgmN2+9ChH/NnAKh7 YWmPaPdz3S5jP2OEjT15QAap8KXjxqUSrc8yXuiDSGOc6I6tW2RxoqEKDTK6vgCeAb8P5L8hKHCz IR08z4jqFxbhTmOO1/S2Su3sx/g6tgnEwZIIqgq2jyIhS1PfbwVaSdHKZlGFshCZzDTIbGOpf9Ej VaJsBSsSszTtWBA+yd4oFJYyZIBkMt4AaWjxvGuUFQsrtkImLz4kCPHe/hmciJVHFscywzd0oQCw 8rwYROJLEPnAOvGUxgbHvOqvVk7aqRvrvG4IBNPy0/RL3F1IK82InNny91iJVyKm1n0ffzB95sMk l2iyPQUeY20VwlTTkims4SiUVWeQHCbsDq9oI+eRcJxjmb4l+eGUC6iK+c6leWH8lAQ8FeWa4cIU FyJVrW7PoRGpadqLuLkjElhyhMeJha2kSgp23rONKNfMKbqWOEiMsIZe6CA1wOk3xu3hzqTsA1u7 C1Cu2uDKqGOfof7wh8GlReNH0qq8nM2F0q+gn7pbxFchCMuhCta9YigIptMaldyeSt5QJ6wdr2hd 2AFam8BGhS//LguatcldAfY1CF8LYss5YbZLl0MhkCseKcSaKgHvTwAxXPoLu5piK5XsZsccr4xc DYFNHk3SSLxVH1ADqYedhvGR9Q3ScgiaNqv9MoZI6mTqleIZchbkSd02JsT+Sh0nw7IJQieUq4Gl 0ByGl+Tr4Q8qDnvyWz8atDl7DHFkXqfDcNlen22almCbGNxgdhPta1Loi9Drszxscbq63LavVHHA zoRlzAhVny5joB0xvCcr74/N2TbH7jTwjuRJNySQ8PB+TkXl9myToiEeEPc6BeI5KWniIDOo9+C6 5Xu3ALvmT8/DHQ1W67g3nCYPZCOpjUYGl2rKJZscEJ2SGNAxab5+Sg3eMLiWS6Hrfrp3R/61fL3s 7xL/pmv5zGt4qK7eoJnNBt9DydYQtPVNlXEnOeUjFaUdNaLKhxCbCoctgtBmuRsaCViA5zDjpTBG abCOHQz3biU4pjgkK0Mh4sKzuPIxQ9OAXeR1RtE46WMS++WS41n7N3m5vSp8MgisBeLx4BgSKoEk RvghoO+3JZACmh+mGJIGoghVixR3fryGftuNdHO6FLOWbuNS6fw0mM7Ar/SYEkctWZWT2MiFS9QC r3FLb6mwuYaynqMfeR3fIYDaDzdCv0uDJJH88Rz1n9o77HsehIa/D5EWGIj/rqsMYXCnD9X/DpSN 8I5WfDiESBslaZpOzT93vPBWVnS0YA53lp8GXZ+DkxJ3jVjh5m9bM/NynxMZhDlzxQSrC9IBWzCr FzPKOITcB/HfdQvr2U1kiIxiSBYlgcwDSxrdjEF/q4/iMGI+XVJUAFgsRgPKeMsnIMd7idXEEgxQ 80yiS4CYai5+KVQiUeMEFqixlNQbUDGC8VibZ2nyI68aLxn6hF8gvvS5JxTxHl5Wo6WxU5sRxlw5 LJdy95D+JLM1VYYYguYR8OE0D7olNaDo53vlZ2j3IH5zCD6Yci7bSImg6J5RLqi0G5XodqFD2IQp emCeF/xE6Fiy1snSXUSTqtvdEMvAwf6lZ38djXaJzrzcA5mhnp6y5o0G2IMgacu+reamM9qPWI+7 E1rT4CNGRllriua+V4vSqLs+bZWgSTY5e/a3yxklPvBB7w/GMEbL0+xfxu5i9cx4tjLaZoUpV23E ngmn6t211VRuwOK7k7fVpRawchdF7tyUJ/2LhH6L99ty5C8Mi9xDc3iajelt/eHAgeGBjPyz5Wv9 LKzOu+3ny/ThrT4cfL8PN+RFYzYErc9i94jwNTQw7+Ldjj/c9/YOd/e585Vmc8PXnhqDsqhA6H/k 2W/r/pZpJxKxL+jPdTbqat3TNM0RM6bdv0Oe44R5pYtdzPjPxvMTZhEdRkSz6jQ+Pk4/NkeE643x 9lb4tnTdkAb1DVc4WFVkaNDMNO0qv8bSqsML9KsURQsmkjxkaEzgGxcR1FmkTjTL2foPjs6fbn/I 7224yjOqv3Kp4sPofdGeH3aiKJ2ITFTN8rWRllft5AaeYa+wdNzMTCZSMwKbqp8ZHLVD8BfgoQMH ewsnz2zONK7hgFZoja7ZDOIZRrRHbd31zaJZk6GUH/mgIF3W/DIHb4ZGuYujduSEbNtwd8eAIivd 9wwgdfL6bYvnqAO4TIKr1mjwxlKLYNhUpCS0ezEzJQKceGeq1YGTTV6JeVIIbwp3PEn5Jkhx8QtJ sOZNFVgMP21ONv95/eY/iZd18yuULfodatCxn2iS6WPN+AQIC4/kpLw/1wGNfuK9pShJxx+mi7ts UEcpHRInIOUoa+JanwEQkeb4fRF8hbmj8ErbrtIXy8DkY0yx3rBiAQGgdssCHffbKbWH6rtxUGCj OWpU37TWDkTRCd04YStpRTNb+Me/Uj2da0MS4YN3+UIYVXW3JJwJVpkRSrmu5p+SNY6QSrui1lej uGYIAZ5reLLIKqz4ddEfyLRb2XoB0c8mlP5cHHDRz43TzxN3XIY4ccpwDSXUkFM2Gb1kP1mDtEK/ NLWEKciGalje6O8mYLKM+RNTsffDK9Pivi7LRiv0Y2F4GaiFhpngSp7wGpBUD0MWiE8B+asOtF/b P+IP7BrNBWZNpS7c4EV/4Lho9IvGA8EfMNGPpzub8nnJxKk+CAGWu+FZ02fJ9RUaLodZjAGNT8XW SWmKXtHAJcjNR07YeUWaPDCdtwqWoMuogqFhSvOlPuDmRjtMCA9p6nvMHktNQi2Tq/HT6p5MV8nc ETCXeaeRLyujxKrW9jznEpQsfTiVVrAjHvHN/1u3scFwWa0ukuryenZF4IVSuOZLe172cKAkrMTR IP6Cwlt29vLJd7KaHRvmd29OlpzMgUPO+eSZY7Fg1InHtsW2422gQ8NnDaY0JDyjKwrHiGDrNbZS ft8tgXc32Ubg+UJp5KDRCCyEUyuRjj5kSSNozvNDytojGL4TK5M2sYSN1d7zU8o/8MBKmCUQhs6C apoKa+kL3tHAD+avYkmduJxaFozdwLgv/GmbHhU1JiEYIWGJeGS8ocpbU/WABXSNrGOtjY1yzUMd ljnJkVRy9MSqI6dMNzP6JIWXfCZ41ATlL9a5HNkGn/dC6Fl4MWiitMLHSrr66vRRezc4ocHWuKWX m0Re5LHotpLIenMpIAAPuDOPGIm5HQYrCipvv7+9fHC0rdtEUt0o4coB+B0LELp915rCMJb/cDQ1 4jPpehuCwymBDmd59m2THjhykQ+OnmfHUtcPkeSWR2xcBTGfgaPZpm57RV63dMtu0vh9u8FHaAij dNeewqvGQ17CiS17/rCbtcBxa+qyaS17I2L5RHbzGmx4/2tLJjsL0iQJkWjW0NjdiA9EnTpyacsr SBCYjjOhoHwEptJIcCEyFuTZqQLKG/prO5JFeQxUk4XCIOvcAKeU8uPWwcukMJkcTfEDhCRmBAJQ 4sSlc6DrdW5yLKWqnk4Ex69cLTvm/mY9KjkAsQXGibp4tH95RiR77dYZU/ErLNCcxwAmfupsWnZg l68+er6U4do0v9Ry9yFMCJSHfERenqCWwhtV7kBZFyMm6Uqaiq6HGFPo9oe4zaXfnxdPq8Rg0j32 D1SOg62RKb0sc2Llt6OUWvbYh+c9UN0WuaXojFE+u0yHLkSso0x4QajZw6GY1ewHqZfowoFYU4L7 dC+yMX5obbbjgBK2Xf6hvLJrfc+ZjrX2lAf3UvbRFY2F91bzSJ4yJZPQ6nQxA8Gv/9VWEE+Jn/bT ACWlEmLeYJKYUkDHAnvu7HS/Z4KanMRnQ/a+vfj497/fZxK6eOBc5qK9eH/6Cs309x88MbUecJdo L9LNGGoNwH12hJwttEvHFBNrWRXc1rSTtzHob7D9JKMskOhdIia8tAwYVTiwrg6YPooS5AKhJvb2 LCHj+ASAEQoowYj8zbtpZ3x39UCDNVafx7/aI0k0KHL99llOwkHlOlzAu6PA6vbvxO9QJL8uz68r FdxkIHGTcJHHQBy09OBaX3NhSnPuJmldLThhxzPmH1C6DDR8Ta/1OwjbYZyLPFkrHdhkCTuxpVdH tWg1XKyJruZ9f3O5gPvOBPi9dW7tma2SCaZDgZZGY21pN3ddPqu3tE8OtZweOulrb3q4dPO7P0wB 7De1JJkkQeYKF+IRn1Ptw+5ahlCbhcqXyHwB/dIk91MpOjXMkeTh/vkxTehtnRhsPjV4wnvJ/6Ip 346xYvC7ogaMuWQXn5xbe5VVyr0jEqOPZdjgwuBJYIASoRMgBFlhYzBRYKndTfr8HWEt44jbDZQk bsBaXdQNSwqWScSOk9abbybS3gRBYbHsXiIEV8KGYbtEvvb8p0SjStuvLbLc2u5mJ3iD/C+5Igv0 SMyKEmuVZ8kig+bBeacR2/JWoGcKa01btyUGV7cPKTz8eqy1iLUjzTagk92PfxOr20BwkT4blKCQ 9GbqVvrBC03Q97EP2Oa/7U4TQ4KHnM+Ve0y05Iyc0AhcxzX40CSAtoMjz7ftvA8aVt9g5GtXO8N2 iv8Ut0yxwjDOyz36v/hNKJIjdiO2hiYimt2MnYG2K2x3e3FozXW22zXV40N4kbC5dAxR2F1r/GZl z2SXssQeyyvRUhnZrt2hloyxb9VC0GXM7GubMyY50/NPGzdWWKHR6FGKXWoOey+27aGfTTXXLlhJ mQeGuvkCYS54sxFuNf1Hr9bsB/tvPgLBQjA5eN3/cAn7U8lEKmssiNftmEsQd83Xvt5YzGeRiMO7 bPNjaAqYp1lwEh8FlzoBxvaCfRlzRmwLriRpYsukdzo465sLJYJGmy+9o9cXpHHwaiCfNcf3VcG4 DYElX3Hf1pXBuPFZQz57XuyvAeMTpfLAKA+ksC8sI1HktygrQ2Q5yZ9TRQKHaP9eO611LPJn2f41 MRK9gs9wZdgd7Q/Ct7+elriw+ye9i2OXK5v87i4pb9+3njR2aRbaiGVhZtcqMfBo6uytOnDYFB2F +bFm0a8EKw+mjyrnPm9ClEdnL12s0PKnfZIXj5ieaF7lLR0p5cYV52Sbhu4Go25yiuUJUV2edVbJ l8YvHPOG0sqJaaHQTZPhUq5Hg503b5rVK9ji1OVMqZVHjxhEfMj8x7JeGbU/vM4dcJIxYbgh3MCm 3nMs4AkcgRYqtEeO8yat0Cp67+LvvgeTBiUxyHjFmqPA8gNvyK6d9tF3y8BI5YSZzApyvpmNflAx jp6lmLU5PAk7pi7POqsgmDP4eLerBg2HZoGbjCpBunRCX9/3yjBMDSpvL898U2wVCB9xNXH0+b2L mpYJoDHqxr7tOlw4Yx/qqsW8YIr1wrZ+HSqHi8HbA7UXu0CQDJiqy3DxLzOfkiU745e7OTEGtI0O XUHlFGpD4ylKyV7fcuQNUA97I0l0HMKd10mc1Cn9lEWThMSmtIAp7jEUige813gmk0iHBuODyinR 2twlhx1UVgZF/qkT5XQ8TXxufvU7W0l+r5FddLGjJ90rPLOQc/MQfHqknFcEd9FmIqucz4kLxyxk oIT93onkyrZSxZkf7icVQqYanKS0FMs5l17nk4UKq9tjLEoqzLHqqLzEKKXNDfXJydlC4cLw6Auy +Gw/KK/tbhECHKuyqgorLHBHwdt6qmQvk5DgdJo2uZMOVB104Yfop5/xhVR5gV6VWs5Q2lTQCiln WeaUha0p4xckjJTTCgMfaZ4UsLqR5uDVErJQRjN+L63XEk3B6qrYQztn0fFobGRSmjiXG44kAtVS KlksTmWnyCqrrLDWWjk941pGZKWLbCyaO4ndtcULF8pKSWbwwcGhM1hWtEfh7sHGS8uEtAOIKojL nMV1Vb7tAhUrje/E77LVdtVObGkT0dHsvSzP2hpdooSych1/Ai3PABNc8hdWL2fZbxykWj3fWMuX 42lleowVwavAbnlpSt6/ngaHsBnFI6n4dZuqy3pN73yu6NYvqT6af/ZHaccBzrXgbPowL/iVgGd/ GFBstjCSI/zA1YsXVs19u1OJECluSOei++ekKzIEd++e/ymlxwjwxKwxu1EtPwHWc2Pxq1enMRJD QtAhPurELijLdGLLxeS1R4TXTT5Uix8ltiqJHAbLYKIQm5V5qXB5ZFVVBbNV0+1Cu95UdYnRI1hs N2uI+fnMQrJaPL8uJeTTBnPd4z9dZGTOMuVbC4Ob0Iz9c/JQd7C/G6rimZlfZnRELdHsm2PLNhRw 4ySjxkws1jDaRotpr2N6pKjgEiqX6lj8hCtj8IdbzL1YpSdLVgJUuixN6xp7Ugkx01pXs9ZHM8j6 r+GFhAGSrHRm3YQMcs0MZViIpw8SZqE4N1BKap7PqHG/e5T4kOUOGr+rbFCdzqcbUvMG4Z3ja4j5 szFJdddt2xCT7U3KlfYpOtAMlbFONFcfs1/4CbUDkMzpb/26APdYF1y3mnVT+LgryV7WmrRY9MJM uvqB5d3DraM+LKPXQ+poZiMeuFUjfO/BVuAj/nyzk2FQc1pjp8icbG++a7/WnSSnsYHkFDrt8ovl j7TEdCsl0WKV5blJEmp0WiODu/oJVhcmKtB0DpTxpf0cvWvNOZ4l9nzzUkjlidHvpDglXP3TLzFf 232fy10P7pGB4GGGCB4YKFGam23IHVrybnf3RIHGV846D8+IxmVWO8kBhvKJHbOk4aQFXWihjNSW 43Qrk2AiJtfEpU66XabtmFATk0ib5ZIRrQvngA5tu8qIMofeBfgzwHq5nGNB7KzM2Dr62t52S2CF 84/O5GiDt5pVZo6OujV4ckSAtlLCiM+uMERf+6TnKU1FcRrHI0oIIVPyyPWIWGRCf3T1+OIsNW5C UFyjJckGpeeAmZmbp519Gm/KQ0gUCaB6qQjRoIVnTs85SHAxKN4rf0QwjqtqCVlsX5BUK4eMmP0p c008lhnkbjxBjy2OBEZpn3spvjAHY1XfR4Z2hkGXTEirY7A0To6EbV+U/VAOL3oY6RJe7tX3qaQd hIDkeJBRTI4x+3mBvVNEgkLFun8pwNFCdaxjaWdOTO05v2I3WINVqow/3LO8SFJ1PexG9cKxURvl D9rcx43NqSxu0eaHu0PWMfg37ZuuLIiZvA4fxDFRyFXXqIWIA0NiEAiNfG7tt4zP7ilBjOIAYn37 EndKuOqdY4ywevyM9yDUPpHZKliOVRLEAhjxFvE+q02GBwE0VrsA9OK6UhkzoQFYLNE35aPB1wSo tBc3NeGoR1FwkJ2b8mB8kMD1DB6tBxHO2huPDjK/5lJuZYhdDwpi4P1ropXVFZ9dOhu2rJznQyUy 1NIpmL8M5hyIFACH+2WJr8sez8iqqHL7DyeZA4ytbKgPlR1ACZZNpmIURsL/p3J5ZNsVc7gGUyI8 qFqa7d1J6UkOciSywnZrjEeQWq+9ImvVSQrQKpMYjel5f8RAX1eJN7p7UhqjGHKbO9nIIayEOUka WFye3yHWRSr9LHINJOfUx7NXuzblVrrI2MFqxP1fpRkSVg5doepnkDcilBB0/QSqsWcxDC2HayG3 Oico6+y8RfjCbrUcRdoeb0iI8OtWKlUBL5tb7IbOFG/1HsxCYPPb+B2mT54ffeZpYkbo1aakzSN3 6q5JLIf62j0BM9ITwXYlYhB3iZKhlmtRzRIW7NIxZAt6naHb7K456Yank1aekN/9QdfFyA4e2Y/+ xDKrePeEGcm5WpXAsChqoCGcalvivMU6xI5rjsLA/2TnQWCpBZaFJg1Xg9sF8Xo6M3oRzdeiHy2j NKIaozf8F22iqevg7alYTpZBiTo6EpqI07FW5Z/pwI7urxZqAf6QXfxvnzqUGBwIqdASBM1asQoa 1Pysd8q2k2Su7n38weSl/x0m0CGOCtaVwlNUvwzamlV833g7mgYhiF+FGb7KdP0l8Y6S/N2mtKYj Vj1gfX3xcD9zLAt4ghiEnS/PZddar4yKppp5f4S5QXePyUKJx2hQPd+GVbLqmUCRgFAhs8364rg3 DV2+7AiOqoOXGU4dt359fG5sjGJWjr8Av3vP4TCiVm7IqV/bDDpccg8Y792T7Uaj+8uc/rbNGDij Cc3ImXOlxQWkd30X1vHh43mu8NLYhyEwnhoaO+O44w11yc7XRK/hk1gf2vFnHFO8ZmcAR7bkaDBy GwH34JNI0g63e1bk5Qzun3bVEB2VNxpWWvDxATqNjuMxWoyp9S+8wZEZ43326tGZuVNoJnjzymdl LXezbKkxE3qTJExn8mX0cgXfzqmadSnlofxmsAoM76kAeExoIRcekqqZARi60LXbMrLjSYx39YH+ S2H2eonHIQQIPaGMtMeR4hpAUkNCVOvHj8GepG/zEwhhCB9/AZiEEZcxSTaEBi7ntBaPAYAwflJb TgUVHyJ51yPzDzuESzBR2sFwhBttmbPyGUwjY42sUNDhqLhqNhZnTvV2k6ZPyKSkibb0r4F77BiZ 1b5KuZMe2UdJobOCXvcy2wAdL2xYcecPQJQ5vOlgBnehHRDDsYP+5XB3EuwGcS8OMwgCCkGJsnep zKrOxrz3T4SKp2wy9r2UbvIf4rtJKlAa/hFft3yubG+uFL1+b0iv1rIq+Ld5b1TRRTOcDI3tQ7lt EL8c0URWPpU/CJ7KPXuxJM8vYKj18/7rSX2jpG0jM9EOeoqla0PLoSoYTDcjS97ESHXheHCT3YOK wwvuvzDS+/KkFiPzD2yH4LzY7I4aQrZ25/+QHEgtNptli/LrhN1ZCfH78hzvPpgcPnQg22PnK49U wq5jrVPl5tWbDtcjzoNL/NW4f08SHx7M+jEUzPvsfP0gqjnMlPoX/EXzgYQTj/9CHvNDSwuowLWo gNANz1hw8lxe1tm/SeNNbQfYw90smy0fCTIEyqBZ+nQu9cP8uGbR2bdjf+yzVXFF1Q+ELO+wgBj4 Qw84GClDJMpTUhnWBuvK69ZlsisoFBvMvl5oOKACKi9qonwOqclco0RK9x657Mi1EcjfmVI50zrE 4j7Rlc1Di2fjz7r2bstdW7cg9qN6xZOwuBhIxvOQmDkszBDfGPZXSGrH7vdFxVX4VcPLN/JLR+X3 bYbsiaA3+7XNfFW0ddT+2usSZcOFy6VvEwxGY1DaA2NXOoYfibVlQ/XCpaulhVORKVZbmJs6f047 VFcc4fAwVsK7lD8yVL/g7LsKKxzu3mrJQ+adyjbC4dpL2qyvWAo32tMU6jyyd9jqwlJWjAX2HaPw cpF/pd1F08AupRnoEI/lVQ6EMiFzflANptn6jWXTyFL4oMp4XkWoLd46l5NbU+lVrIrhbVZpIQdq fQee1+iiCYfDleoXQ7fH9dyZlnseDwbqC43HAvLAh/be9JfbTwZNuovFEaPgPKYxrJ7Xjp7CwoSA /fNc3VCBFFUOVzGHIYd5xOgWdYRnpB7WZ1EIXBS2GUsfkymLj2nCycC+CNp8iDYUK2PFjCdeGEKk bOxH5q5nKxxX/osS17+GubUXmOxbFBPtNgsWUKxyq5EQGxizwOG+9D6/X8q/clIatq5+NLbxauD2 K4jZYwTQp/fYSW2YXUY7r96meqZocaPE2KgC2wr2MqHyCFOY/TR/hFLwV4aqgaGD2OfGtNlECAUZ Mfn8ffm0VuM6b/FauMog+m/rpxWX7NCSlRUlBJs90EK7VKq3F20dg3ZSe93OYbxxDgk7Yu9WAVU2 Viyvst40SCt91Yici5Rf8ZotakNineKGBkyHmQQO+xYWhdaM0WrHSiNMWsg6Q0NBwfdOs5FcEYg3 aMMtfQ3Jqf66d1ESe55BXqkc5EzfLKRx+kcYcodXmShiUQh/ievPR4FQzc5EigDNi9gXukwSxNMr eXPpKUhXQQOtFJl/j+nwR3mfDojSYmXjsEf6WeOIs+rXH/GJ1uKV20tf8B59zz3NuHFhQ3D6ULjE l9vSU6ZQZOmboxYr9k1ACEBS2n2D5JVoyb69aAlXBo1vMaFgeUb9Ns/RPRBd+kU0gOx2cIwR+XFe NwshDuoUjYrgOBIBriWzSygLz0+y4UVTrSuXS3Qd9c/twSh7fLh6rDqaQf+e+WM+uDHNrPkYiIY6 BaKd7Zh12nGEcTShuBKOSStW0OEuRpBkb521qSRccmb8Imhdco5Gh2tU9xoP0Mov1RW3PxplKo82 Gax8Egn/F96XBAV4GLaINc0Dk+s+QHr7QYJ2emiRANf2ZDEeCHMcj/ToBZmH9xMyr2UgcO/RPs4Z uG6NyX5N6dS1caUfd3jV46dbHttieIHlvm5G1jwJF0klbWcZbLvIra159CXrNGrgrezXMLyGH9f4 DLxL8gft7s+7x5gkxLfndmHJgXwTzD3zDRWQ35xdCwUS+KaIMfMJibSE14+DiWATFI3vWfBGcDdW AjSLT4ValkQJRiuRdUByLF8yRjtX2feFnd/SyVWxby08hzSGH88/++13fePa5g3YrbfW/I64woqH k3i9+o75/EEXEQJrnz9jQZoj8vmpdzcYdwKbjFdiLcotRO0ixsvZdnnbyl57DSZnt1ZB2W7zallz kcex4WxFUNyBFcMS6r9zD1+g+rF3qh2P6s8NcWbbDXqIAFafJ/6+9Qvj1s4Ji7FF8AHjLxZ69zsX QgbDMHfJ101WsaueD1gXwcY12xug7UHjRROz8E6JwOcRO02Cd3+WNeEXiQcW65EZyl+ambYaW20o ai0GJFLUCcv8bGex6tCc1pQV1B3XsghpVaOW3bvLs86bhuWSBu9UsX9qwqbX2oLq9ssliJNqqcAp nqDS714YFyvqk8gxIBYDOcbOl8suM5w7I9bkE3n5ML74y/czhS26LtwIboxRH79UUV0/o323i+L+ nGWS1Vs+rszDBx9zNs+OBbyryI1116Lzbvtl7mQN0TVP0CLixOLPjAvgn/CdUXgZEHGqUEkjAqbx uU5TplBOpYbDDdx9Jpnl4QnJ2JZPnkUvPpQgT0fWe53MUE++Rv6Kr/SG1fwYfXquDRizxPoIT3eB jTgyDDiXsQ7PcQpDHaPzZzm2m+jZu5eQKlrhQCVzcskNjSHWBtOxrAXHL65MTxgadk+NnXGsgpMm EuvHqAx2vzXxaDlbYu877zINO09I2ZQEM6h2eIETjKngiotn6fRiCppScMSevkIwXHWlqFtbIECs /PJwv2XQvF4gWqFuhjlYwYlhHxaE18xFpcdLUMVC/brr8g8Wg5YhnaIhfAfxkIJfoLXiNELBi+ih C38fEoCHboRr+eMOoVlh2Emx1mgr6+YnVT+P/I5EypIslf596yBqTJsgEVJR56fpJKBKsTY+kQm/ wa8D4wUf3WTicb+ND4UDAthePBpblMSgEnBwGAuGI8D9X6SOhyJAhiSKxQ1r72jfWr5c9vfLn+Xq 0GrCzqHbE6n6wqiC++RH6I92UgpQ0iJwhtPf6GFFMp0AaxxJtA2LzzdmHfczXMSz/5BIW3bv9Jih uiPxA5NrfFze9gQEIiYSFnQnCxLD9OXInOhDmDorm0PQZ4KX7ex2Qo9NRy3Uct6FkKV7VX3xwZs0 z5/9KVy09+1jS3c+xEQChJJRczChhOU0iqNbienTLWVHxXDS8f57FpQPR7H2inJnumG2rEVqehZU hKAqbWP8huT01b9hNjMbU7mUeaN8rqw67D/zAvgR+aCj9JSytiGvyxZYHQ6cYXsXvWwfKn3nu7yJ 6hKczW/k3jti36m/Xe7uWlpd/MWrE63kE1E60KPmnF7DDW0zBg914EVOINCxqAK4AknN8z+zyyUs 6smjQQ2ZsrU4B8WeSVrD9rHJIUauAMdHiKuaheUUYN05RbUtnoSiZFQ89GSFqxaHveKj//ogFjd6 k/zIst9qcFHDpMfPzZ7kIfvubGjAqqOVCbBpazjy4k/D/HroqntQkr2c5n7O8qpwqDCH3Jf7tqJC O4WNC5xB+XTzRIxK4Z7VXZmLzvAa+YCg7EfsTtkUcA+8RYLKe37eGfhdFxvFyxF7dNPyQfeDdzoD fxrJPrXn/14yhYvOPW19oKyLDCK+a3xzJnoO5df81R1GyoiIfWCHvRsPletuwTs14Lxh2n9aQNJd Kz3/vWsY1+jevr645dfusFNa1W3zJtS3GgKuSo8Nw/jLGOKB/7MeYnVybaN9dgPTyEoiq03xvNsk HNabxfzI732IeokEBKLDa1nB0t9UW7enmLMD+HMur6WKBRF3rUFYuOx34Ep/Mrld1ddVEJu9lrJh x9ZirXTL6Zv0OM/sWjMKTbVjmvX6qbTfsl4xhpPzyPByfmOM3JwmctNQ9+TZVLOWJYo6rMTra014 ZMDgMZjVUtxkTaWkJmsoYbPqpj1iGl+ZUc6X3a0N5ODd7pjuX9FrXSJox0vclthx9ddqvH5ka3z6 kkKlWFu3RKtykXft+MRVquU+896iIb3NvLs6OBLoHumYR3udfOOR+QUGN5Y1UxsQfuYWKZlqCz9u QEAHCKS628kpjCxBAsV8bMYOKQnu+dP/+Y1020nuQ4gwEfgp/AS2qSkpTk+4ySLV/eXCE2gLkygg dZzavB+pSZJKZmI319vQp+mTBB+lj4savJ5BNFxx9rwNGf0mSdjHfgT4jSaKa1EXJYFEJFPnQo2+ 1fxJlQVzTzv3/Kwkc8F5NiQqM34/VQykxj6D+Gdu1VEdtoEA6UCz5suzJW4ono7nP4Ti5jdSObU/ QHnqrBQhJsKLV//FQ6AHxs/dvSqNrfBz8mMTEyPjw2fhuC9DTA8BcfuJaDZaTF5xAZFSLCmGM7a/ DGzn7x+wZrpT6JSU4+BcqTvM0ecJ4r6eSGMbzY77RyojOSzZF+PxxXDTdAMx4FINAXDwQ59nEYD+ IH2Og1PMvY8ai8dzl1XVHb+8y3R2OORuuTg2PoVO3T/f6WtYU24psJYucxOr25p+tsVy+fbk2Apg lADOl0oAoqjOBTvteG4AWxBFHwC2sNs66BvMG7W9dWCAOGV5ixWQ9OlZ7rUlHnK7rxG+8wYrTOE2 rPf1MrG7ups9dr/7AtXb6A7SeOtme1isDj/gll02CZgnfKGqGR7O4Ibtiq2BCTxdI29AESzjpeLv vpYK3Dvpwg/0TZaaVLKnm/fe32sxgifPxS3mTqcJH4iy0ZtsLO3hIqMvOH/3NvaoOU64zkI/6/bV OC2Wy8KJxVO17EtvWapte22RREwpqnYUgBJ+49wBTz74II0xm1TG5Tv/ZykhRGhldsn9VPkZcF4E jUz3yAXk0fmYctTTu9GQHn5JjBgYhsSv2DbbGKMvDUvgUC5+Rf2BeM0nJqhaNFCEBrG8XNOejUx7 mtP7jVSpwiR+JvOlQUm34We8LdOc39CxykZ2DA2NKWQaOSl1oH9OEvORJhn6O81NlZOwibaooKr6 0JiZHes+cGr0BLYFXWaLnj8DXNC2bGhlkRZP+OyUQpVvJdDoUdDSqDCHU/sB3dXF4QvnG34sYEma bDGLpFaY/1IdHG/rE2lUh8pCmgRs+KCe0hjVBLO5AS5hk9UvDVMw7zWvRWTK8y9P1G1e/GWba1RO 64p2fM2lwXQlVAKvjl/4LcoljNBZJt5qghvneKRtl69aVNzmexZuwsQ2F7Bs3wAwh4M6yR0GjQWB tuCHw8pR7YC1X0YgMInDkmWr3feMF2DolJtqrPm1FfbkmaF0IBrzf4dJ9pVI8XBHV/dGs0kPr2hH lmBIiRImUpKN26SO3bCkhU4mx9iT1JQUQaT8TE+0NBMBNPHbzEINz9z4pT4Ofhr+UZdq4pb6RMEZ sa7EBI/IFKkolq3muj3/FtSGTkc1Ae7YA8kosraHcbyrTQcU1TtsxIwNr6qGE17grX/CNi+pMHyI gdgrnZe3sImJPndvHevFqCKs9uIFixUIf+l85a53uM+MnPqvMCiqXwwSULvaAgiBFXksa3F1Q7tT +XQWUQQt+yMIWoOLObXjBWdMuImY9CQc1Fj3yp/DHxYpp8zNIXtuys3YSsa+n19FlX1xDFuXEn+8 jxNUB+e7pNsT2xkf3vzHg9pwPp1cCW23jeZy9OLt9EMGZ4DQrtuHap3j9Hz+SEFy2a15pjCHlcp6 lZA+6WD81tzit7ydO/WTnkKSa+ftsSBenr9ggB1cFaNLSDi9jk/Lno1EJOqis/UXqAK7s2CulnXX qLJcuUVHmILfoO0yFbg67A2wl7oaZf/IsLLijnlxiA2xXfcGlie4HrEGN7FqAImUZGAQVOoNLuGC virSR4M0X9/7fGN/0iPHA/GRQC8c4CoCVtpKfDf52lhgcdhrd1Xw2v6+YLoEgA1R/zfv3+SzBf3v D+IuQiFfmhDTOhgbC4vpQ8jX+YrdjXf39z/BoLUGypuAMbORWU0DMN6jghrdAfkBDfddqrhDNfEf mTJO618WO3rcadUt+Y8+n0o8/GqXLhWCbu9RQjC9IgWTKgvVh5/HCeJmms67aHqgN8/5WBjPXGZH dS3HRBBGG3GnCvXdP2hkFN/QE+ZZa8AJH+BQ+YQE5WQzx5zJRv4CjxkzF02BEP/8mW+Hr3v7z8L4 9UCM9TW9KC+8/EBIpEueH8NKkbfusKcyaHfSrZ2F+5cQxDJoxzHVucfXMa4afe+BIQriWfanLbhG 80R5xDMPrqQKNyxMas6qNOzCS6T8eHK6GuLzNxsZtcEr4C3dO+XUiDBMiEdSwFnnSppCn79oLXyF hW65DWjWHZp3NggCm40QtvIew4j/y5VWqLoFTaWez3RSjhBOQpAvPYk5Uv2fs+Ru4uMT+7LO5qQd WMhGA3mtpY7pJTW/WOy32N0NGCsN2tNtPHOAt2YA5IJrCb8sDHG0xXnNYyu0+r6/de1JN/YT6ITE u1MQX3G8Nez7cMQlbW8fjjHfMRGqotZO0N7dAOw2omBsjDFVG+ikSMlt0AE6VcS26caaHR3KYFfM 2eFpLE1omvlmQ7b4l3O7kM4DyL4Zwq7JGgtyC88VRrn2i3wDiMJmdmScbEiN1Y62aCUSmp/mrYRT 71bkuSqYw6WqXqqLEdkeaeHNeexllcRTLmFYo7nobfliy3U/S6mTGlX42HAyNtq3IJVzOKE+gnk3 9IOx/yd02sK743IGi89cHBqCZQTIhINbubjzbhn+IpahFBvvLOjygDhzqrAFedYe21mMHSTtAKcO uVogWZtxLDaFd92gqeAfcPZ0TLn3mM8UeQHN6IKcmKhMbYmOR55qyQ06cecqVXXqAizFe6cfsbTw XXGazqXbmdUa2+DQl0xGKsFUgu1bIflQiYgEcD3q2emDtGicIOy5a0Vq4HjOz108KHS68T1dff4p lam8mJD7S5tocdp9Gv7k2cB3dXh39yvndSavqprdKMxwZdUuDeuAEP6OPA1ZlSK851865a+lTN8J 9jdFqFkkW+BwOPSQaSaEEsj5k7JgBYsm+HzrMtd8K7hXazvick7Fqku1xSpP/iGGEMUsWqXcEgrT 0k8GBsXjb+StZT7VEv1ggVEs8Jaon6+7zHB3re8T/uCCwz3THvj0ApceW8IzwzEYEopmuS9Q1tBP ucLllRyzZ++VjeHOPOTVmgJf9NFiO0q6NdYBJ4qK6ZQoG6M4U+4mAy4jyfau+HyZ/Egsfu+RdWdV fglVg6vI/RWSujHROoa36Xa//6Mbx1n+TL/RemuoX2HIhZx6WTaskijKQ/ds/tvf1qbPU27NTyU4 KdA27mbhCkqaU9nGymHFrMW1PzQq+QucYu2RYh4CWKrcQX7EY22EvNxuzkpRvErG0zwyFX/xp4/5 cmmGfFuH9j7gP2XJYTG6DRf0wnJahMOMPg+kFyP25bj4G64Sid0q8huaiyr2sPMI4kGE0QPgAltu g5UkWfjJdDaqFjx2WY4qmW9RcZnc9M8+qSVIV9F/IU3DFirSQi3nAdCJAmrpffrAMrYM30ajZQzS fjT5QRVbUhq+S6Fh79NQ92y4/NZ/hqthVDqgZE3ZVqWtqCMVzFcRzWGe6tljzgrRIzod9//avv3t 1elHqRR7v9mYM0TmHJWL2SVZUT8eoDVn9VJOWUOzyijyhiWJYepUHC6w+kVDjdoVrmzfWa0BIzgJ ZP858xmpDFuQFsBDW4vgG9M7F8Xa3702yXYrI8v2lsqdZV9pH9R2e2rds+KsOs3LrVvxqZbzRrkx WbLat1kppUXeB1Om/Z56y1RPixIt6xeyXAagM62+fPn1Ze3TL0kta/e+UPHHE5LLNnu4KagD5UtV uo9Hahtsp3H1Qhx0nHK1vMFer4zXrLJoomngejeC7rfU3fV1bScFPzx1SueKprXe51okZ9S45lZW u8gLdQ1Xz4ndRMspkufd2gwTUjsnWhuMN/W/HPk0zduVG5oVdS0rnR8xR7wamOBZxZh7XZbU/iHo ddmjmLnCnVVewaXpFXvKNkfkSQbOJd5/hu+jBTuXOX700CnjXCflsn3AFFcKlzj49HRlafYUebnJ LPpxfyGZjTpy0TD6ceOZl5a3M6XVfKOUfsDhiVOyZ110FXbdtHLuSS2VEcThRsF3S6Hz222N+JT+ +8Faoh1R1H7BLMHm+T8A/XRDGm9sy7aSj8GNIph89bww9YuMufQs33PbIkLF+746gksx4nGWgV69 qlF1Jk4zAmAEjooXbgabb5kUagQMX/w+VMWmjuWB3cRQyvwUAkRlq5SkQEvY/MjWUlMnMPoRMgQo sKUY1ffDU2r25KWMJCG515arCS8Mlj5bVhnnozCXG0zxDLKq4aIVOo7fciktzRRN1B+62smLhlEP ADGhoDNTRB+VQK33Q9DG+QEoEhja3923+YlfpDnQT2HzYkg31XQN7dVgmQIFuVCSKii1MKAjQbo8 QQb4iszQJ3LCxJf95bpYl6o0c7K3UM0KKlDCYLhxX10H9ZsVkgjNTAQodELieGJ9ZQcKymdMBISO vPF9OzBRSJ2ugnhMJcht2gT1Cg1qvW6j8td5cHQUPM8cS1yVRVfvD5bybKvfLatic5WgwdyHS1Fp qu7EiUTkEK3KaS6GX+sFl38KhH7jMWj44A8PmiMmjM9yyc3bRfkjihfYRmrlCWE+YfGPkctbDmqs MtNV94r0I1veZRJExMAM39RTYkQsQrO+j9NvjddNeja5Fuyf/UwRjXpSRiQv3RQCw8fVnq1jvSBn /Hp9trd3G603dNNKzXj0FhmCDTUn+8M06nB4LhhoVpDKLJcxE2l3M7ya4bAT1FMrTEaYVXknJ8SP b0kVpZwSdZF221TQ8XQMUYc8inkqFjraywxE8/ReDI0mVOqz9smt5wMbciuRk/tlQt+qhwc/r+wg Eqw3/X6BtdmZKvLWc3bKXm5bmxGTZtb42uLtZ1iHaf1EjzV3pvkEcGujImcjXptvklwkWR/6q8X+ xkcBqOFe3HDUtcROw1CINtLIXl27mT+vP6cAweaRR2OfCBf6AVCvcDVpiupd7SadOho1Frgq+Q6S h4mU0Z68GsD0tYJYGaIG5KUwRDcOiZNNSyS7KSy+hDfDSH/T/7uNcyFgef88tKchhhrA76fiS5PF qU0Hg9axa9igOA5AZZ49cLnjtwy++M0EOAYr2alkP7AUMl0/PXKohh60DxpVGTLrVTFlOJM34iv9 7yaie6ENgdhI2DduAsKajUHXbcsCZIdt7q4PtJLKqnguWUrnH7tWVWQNDHjuA4iLfzQ6EQgjUXeO gMJlASHJeJ0OqWUlaiEsfSjutFoXXk1fjZV+H0GZu/sf681kJwtDOYNyEy2Lqeu5YWv367aXc3dY uy686tns/aleaaiovbK5K86oSE+VNnYTkZiP9T/gDP4ST4SFVicKNeYTGpsdLlu9IshTqMDE2UJJ punronRJbKGFz5y3UPe0x4+BHqQMb1rlgMjhtOv6cYrzd9a4rGJxsNzlTAAOtCit1EDw3Fi2mkyn wekbR2G6xIhr3WmkD+BILyJ914XpynrysmCvaxpbjFAUXymOuRTHvmArwMx9pHhLOzVyKZA1Ys2V lV1hqjUruoNEKCoM1iGPwNxZtLb/8N1fcqb31hp0gcrpFvAmI7bovSPxtqvKXwVNUtb12IBB8VvC t77rUN4o2xBzMRt+imKAOd0zU9UGc2nI9Xrq/iViw936fcoc7f5WMnFyFAKUSOLU6IkRhN0IZpIg dfgnBI9LfxKjRPYXWV0gwsnEp8AjUmCp/oEb6FlIdHHFcJeEIPlgEh+hXxcpz6L6vxa31KsUM0mq sNnR0Fup+KJlOq2CD+pC0+BSIa6wklgrVa2JYhjnxPYgAJOllFqYHjT+gBFu96PiQP/c3EbBYLIR 7Qw1wl4lEnt4wJpMGivxu/ja4BC5a2ryQgvN8WqPtX18/dL5h2VxvliaOVNJplRm9ROtXzwKnFzg kn9HHGwEPX1CVE3yPRuwS1n2PS317SgJ6UpDvf+PtV2htaANpLjkHenLt1BqayKlm4wy4K9ZYN/s 3zGyiE88HfPCEAzCXtzKpvPm/r8v3Fo3fXOjEuYh8aheI4FruSAED0FJS/XPYmt44hdZzilxr9zs vPZ1gv2rEZc5IjV9P2GC4dgjpbIHXc1R9CzgTaEZYphRCt/H/Xy0Qi+IxSpRRmAOESdAYRi/ER2A BVF2PaKtbH3/2yehIE2lX0GwnpfAv0CAmPplCQjuXpTmkh9SMZbSyX/fK+MyrBLwKg+aMjKvmejf r6PiJ49E1N7zgwdCRRcWZJjLrCArn9ZFVX4XnLSGhZpZzwGiST4DTbetbbg5k0uiyeyYS2ghwVqo 08Zszpzjo+LHS51SY8QU0XhGaGbACjJOZZyIYUVZGSmlMY573BWqpKJewLh5aDNkRLlN2zj8NIiB WISpXgVjwXjoFh0PTaVSnmYUW5NdOgGwS2I24FRGiJd7J2t/5uyhr0chhpSJ9zYXqFpxT9sjBvMf L1LJowYYOfZv9RvuP+fItGtwnMl3mklkhDJ2aPCfdc8KfzhxsyquPKH+/Nyi9PLtLAoSQN8FKkNL eiO35+KPwXebrUw8Ii6ifaK/xpcwfO33uban2Y28M3Qwhu2gr71+O0tyW4JzdMy7yb9Ue/q880/i saSDEE0lUIl5pKD2fG32lBpz1R52Z5uRg2gI6AHZVvlEU+iiwShJAVerapWOujpXj/6JiueCFnLd MYK9mcUBgd35j93aTdl6cbCSt8/IajbLDzzcAD0uhMKg5Q3Hofqky29edfaBS9ZYmC0jvQ/Z8Tvs MZ33GmH2/BO9ftjr83QHQC+sLqWWp6E9qhXqWC/afnQ8cSlF5Gl+Pw3SAC3nqs+IJiWeUsP7Z/vb 0EtuPaw+8TAtt3zqlk9HPvmNsRu5rxOceH/6GyPmQr4GxhNkKwlQf5pnE+ixK/nlR9spNo899ZIt 6Pu685U7IWHqUOMNkqB4f+cxR2vsyQQ3le4dBznhXmQOba+vQQtzDVhs0XGg4jp0gCC6lOxH3Ifr zoPb7N14KIGrjlSyysGy4aHlGCSfLrg6d5z/8Qz7o6YexIX5ZhCL3/8icWU/vuIar6qe5BXm4w23 dmNDsqD1J76qqvzi/iqirvZ+UidcCQE+ayDdtZB3dSvXUGHx2cKMnv8Z4T7V9QpFDbXlFq6+eFCW uDThKw/7VMQ1Y86u2ObmjuTr03kdBI9j+CTCb7ASjPbkS01YjwKLkSnHsCtKgKHBNlpAIgETpegT sO/CqxQC5vcG8VACNiqKqysdNZbtnbgzEgMtrs+2o3pXu3fzAh2aeXgXZ9DgSxo/5tWQHB92eZMv R+bhpqT0gg3dLOVJkF7kq2Fr1LMZb489FTDlSl6izO6CFtZK3ygWEyrakgV5RbNe7amMKX9EcBO4 MeH1SociT+siFvGouSNIuvRflQuU+14TEvfm5rljtyfv66uwveTTH7+QfyiHMVFl4TiPq8Td3ehe eLm8Ooa3ZtCGLIY9xw9ktuwfhSYS6EVzzzTd3VXtSoWqSDsGQv6tgJLXEcPpSgg2MQtwmDyBchyW 4IbY8YQvGJyIWb8B+P0NuUYMUgR9oPpDfGL4eGk4Z3SsaMA8JfqL47d+Z363dv6EuEbyiMm7Ds5t bsizdTOj8ve3Lz+mccupApVBK8tnq8Vj1SaxdfvoFdo0tFwSrTsqoVOSff+zGTHTE/vHmwpTlvjl nlazTPKmOx6JZlad7xZAQjQQ0NAMCdzVJom/nkwHROu7a3erpPX/r2Esh3ztj3jWFAEraWO71P6O H2EMydtmL716ekBra7br0LwHa6R+VdzQpNzJjXJ3ZPu58uAcIWJ4cfzaCYE3ovFDucSMgQUC0KiP exNOww/J3/x6gqt56NCer9qRIgRVze4HmxNdjdQF/aqDpyUnF5GRXq/NB1pAeaLVssdyNyuDxkjn WPFzXNvvI8yRTQPINCXDcM8Ktu/YuGUS+bsui6str2rYoqX6mStZkWINXwpXeLStRRrTQqxcX7wC PBtw2nZf2NJ6l9x94M+ooZwWxGXWVe6ZwlZkKM095Oa4PQcERXFrwgK/j+EyLqnnoctWPNh43IRg Q0cz6VTcXUmUTEB8SRIeFnwhkrXxQYz8veTO5Ej3QpJO4WT3KYyJjEqX+1DXelyaCdKbgWF3ZPvi n0LRRd1nbdAeC9aWId8Z2L0eCUSK/Y6MY05LrPttwEyQ6BZQgsx/3ot80WoSaR/ZlbDriRAXwokt ibxlIKR6WlxpmdAjYmBWcXHkexIwbHn9Lxp7VPKJPhw4tG0I4QLWb87aZvX/LR99BphReOnEZQZ/ 69lqFX1evctFxQ9vGw7Vas0EusSly5mtjqk37vjRaH9t6vCwk8wtwV5lnjXQ8lrLHnPbwEW1Pmp7 DSlcWtbvHCO/D/L7WpZbz4VU5e4Y79k8tywKYrJpgTR1EcanlUZgVRhbg9uyKtlZLbeC+Cs63JPD eQPa9UCHLRGOiju+y2XTY80Nm8DcGSdHr/284n73bWxj451+aQY0XW0UY+zR4HH/yL1sslOs6w60 Xw5RWyB39udj11D+OAZgsb+YJaFKvpyOw3P6Evo87KW0L0Q/kbDhvTJLNq8ujmdbAyWanQMIiY8o 6qRdvzIOr6VWZkwxJv9j574mVGQ0o4/ychqlPfwR8nS28GduG2K83XpA+tac13pp8drt9n38vZ0F Q10HPWFcTEMRY56i98G030ZRPskzhsrrm+hiGepROC9Ah1T1yh2t/8AIya48l2skn5TQReWuS2WJ Ah4AEJMy5qWXNXiWw0NFNp5J+tkoijBjANOqv+Q5JH1JP/Jnv0/CVvNlFL+vnYytZjkYWb2jp2tZ 3lSAY1kh/ekuCNBPpx0OukxfaZ+szusaGelxlyor7fUtjpvI47dgW2RSSSPeX0vtCSGiHrIwGwZ3 URaxPWdsStSO2tvnymTfDG8ehcsT6tbGaf7i52NbXwfr2rqFg972/jXEy7WzL9zcMHWFSp6cZK33 CDfmzx08lNUVKkjODq8VmvjANUxQuP/Sd24c0wuyzWd0pWBarlzJm5ivF8yQyOpwBUkqgLCYZ1o8 rpas0VKshf7WqPx0k5aLiPf6iZJd25IzZeLBsDJ1TNcbJk63+s4hOTk3cXFTEKMaTSZkCKIoAPwv 5gDNYDfaL8yx7AM0Hfambv9+3eVGr+zDr8MHs+EOGt/5GFACY+5zVjvDCql9JatZXepYw595wlVD 1PrL3sYQO3UE7CAZJ10EuPt5KgUIpQVJnyGtLMucNiwISxq7IjG9dBpffCPtKX6YQRR3lfoNN4r2 XSnuBTZNLOMsE1YhUQpls9ypuetC1CjxcqaLhzOKgLtKb9MDP7h/JZcDrzurunF5+Mw34UUS/cSc 48Agf65tUzzgbxScXqaXHl6WMtdodGYNgr950SGYj6gx5DoPDg2i/k9Fa9IooTJtXgXjhE4mYWvJ wJlXwPnt6MXDaA1tazSJiuu8Kpny37gmEj3VDdJcRUGnlpvyS+6coh7OLEQm8b2komq3wiQpLgo1 PXBfQ9cUmr1xxyMlFdDYwJ1mYTdxxlQcW9069fd6NJd1oeiVrXSYRlwT/rT7lX7Wyn7X+0tOBG7d OQRhT39fEmLBB8mwtD77hAiUh+0VzT8ihbvCQrn1WJR9NEthTISEzpxfyxm70KyvumdQc9m4besk slZo5flXO+d6VctTbTq95m4ATl/KdhWhL5fbW8Ux/Sv4lTks+zx/T2xV2rWVZxjTYN66bqbn/Bdc ymws4VLNWYh4RHdAUdEYHZp1mUlAX7snEKeAaWPtjEWwiolNB1Isu37h6jV25PpjqrNFuWkDW4Gm Bh5VVbubxeoryGX9BLFKlrQXq7AEOaxdPuqoXBbbP44CBTH6Z40cVU6Mfrvi+gXoLJ80i4BCG8Hs 57RNM4BX6ry7eP4OSD+/1S7w2DlIoL/5fXP0PERy3rGq/aQ3C8nIjAEtbCd1X57SFAkXXAK972fM tex+D0J7uAK0F5WcvQsTkNemQESJ1C7KtSAoGIJXDiL4tJldDK/He3sKPCvAtqcgWiDSEqLrR4RZ K1jrAJZ8DDyzjV4F5xTbvZuJsqP3QHV3wXUL3TV31UZvgDHFx/SGE6Y34gYpwaspqGhxispevpGp 17LTnMoFiGf32TvNxvojOb0Vx2GZ3BIc0ZsFGL0/ADWMoQad4Z+IdOAOhkC+5wtYz0BsOC5k6QXh bWB8ghJGYZmR0z/m6Eo99ZdJHCXylTSpjEXbvkMj93yMhTLaaM/O9jmCusD7VPH2ASWq+Txj8/c5 2WfaPt7aTn3UjgQ7X6J6lwLJaJFUd1pT8vbIR0UqzxYQNGqHQv0unOmxL4ifKI5pPjRPNxlmzP9U g5MqzDBda3c7MlM8CYyCST2jHmBMDJHaSePljWWZ76iqAcAauUTOMOjqQFBz4Q5Ph5gaoyQAGFW5 AWrD1ojoQZqAPHIKgJCmHOX3LDg/2sdp+d1pj0lcYEnvSiDgUbxfDeBIvTIksi/TvlxH5AcQI0iK qH0NDxfDiw4fK4KbNiCkyVRRsfhB3U6FggFowYLfgywuL2+yWi6ox0Mg9pNdthIR1OWgr4BVLSYR gI0FUKIBmLr0gCmQidnQV744dHVN5IBTzhQZAiFPZdAHIl9FJ4fi0wb0KpCWnk6zoaiIn1BFJRA9 rpMgS+PWevKTydnCVcqH//+1FG+wKlGLKATCgM1jCIhfusp/+OjFi5IYQKtqqGN5mfLfjTGUQLId f/Kts6nElEExZkZ9Lczssfeu/c5ZOuMX6xewcLUAuxIV5rfF81i9wTyvMD/Omrrz1WdMdIY+dFFk yQuTaKse7KkpqAvF1STjDHIlK9sxw5uW4xtnJreSStqtVjQbkDwzzww+U3Ffz8omV9I0w156Lc1u VwH6BgPjOuvEnRnR1sugL0A3lEsqg9v3FgvPMvRGgzE8dKc2N9BG7RHAKGkuk9OZpnEBy+ntYwB2 enl7V4x7IgomQQoClodOCmoEIKSkWHe0ybS+y64JYNbtjh5xtZWRsoVC5VCxi6Ew+1h3tDigXflV vHD7RmfbIULYcvMBAo3ePv09ygogCf43InVnFzgRAJSzMgwHMzurRXlI0D7PGx7DgAIej6TDGypu Axw4tdSN1jhfvexc5wIgpJr1e8flg0V7tFZvflvnjGVyC+7W5IiPdXccDr2hoLzQY9q6grt3Y0xY 5/x+m48Z6y2YpOq5t5FZezsZtK/7NidYJFZ0a0tBFSUl1X7WxSx1vvQzYLTSy2iRV1CnBwe3M1zw GP3H3nljb6IHO2Yc071m8UKq5Z2O/EMfcZ3H85mPsSDaeB+uuTtv1Aa7qb48N98KXfvMN95x6tpe xqlvVgE/rqaOGD9aWE0Tj1sadvf3LKJane/IWw63MK/LBnNAVxmuwb5cZ/DjXuNmAAtjy8JOiV2a w+imon28W7ebemcWBsJmpwPg/pN2lTmDcYM5EZ8HbZs0u2Xptfny8krZvNqD0NF7XZH2CMW5MBf0 nsw51rqCJhkUahbVOIdzJq8gYBCvfzlWPAo9p1/0nMJUPho2z5MPPVdbR7q45uq3Fb87fv7sjRcu oqJr/n3w6hrg2Bc3d41Q5VyuJrcQ9KtiQyUupxrRtWniRRfd0HVYVFdf0hfEBGtMgTnwMFVITsRc iJqgU+Taf/65PQegThYsP+GWt9Sat25RUB0nAaUr5goXuJHUUoQ5iBGhn3LDUSz0N0vW9zNc4SLG Fk2aI5bhEchBxEwKuU4bGChUhTtKNuqHPYYhYNZBC/YYQ30EmVxBbrkBiNkqkX/bvb0P1i2sUzCm nQ7xKutma9vQ6FBb2zVBjQph+u7YMWKEbazzTt/YCizmzpNcBAGAJTXoZV7x22jbpJRPZeXoRc2F YjRi4kWHEyPllKXHzi7ZrgF3HbAYu2PqbwwYyhdZLNQSeuPjWYwFCYR4JB8DVVPPGHJGEggr9pnX yvf8UTkGZFCXrk87VgKeXOv/xV36hoD464u3zuIr5AmLMnEhOaQZahMH2y1amSDfd3T0t5/Pub/V G3f79WlrbmerM/K/WG9o72jTryloIw1sGc0h1Kj84kZHh4kleTkthis6DZCxfAkBkaKGAm2H8MV5 uQYDhxguZ4jPXoLraveh7mdnrnjd4F0+6Z9diV7E4CD9JDsctGcVulCL0ZOhhgPthkjYUUhbAX1z dreWr1pDDX0Vk2sxabvYxZj2kqxaFcfID0gfHlRtKlLmQFKQET0qjwhhF3THYRf36+mVYHT/JFvK AQoBpn3/1UfHlz84JJ7/0flvAmlA1a9OnVtvlY/ENVqninusuZO4QX08Q854xX4VNPqu6kDhkegm N6kootkyTSy1tGJEAa3sXOc+bD/Ptpe2FyRh85adsWzfCpYzHWWSnDayByFYFowohwbSavQ8aHzr z0bcS2x7gb10PxZPHl431GL05BKhLhBRRrMA4OHjsiRJCwKNKyWDxgpXYFGm/52h/bA0spXpPIJj RBrbN5Idm1RNjqhGinMiw2bAG+Nmb4lO4duhXW5n0c5RDN/s+fFcR+mqeUQ5O74x3RcjZ1id+kPl 9j2X/jfcij+FQVt65aW/T7/jWh/fbSOyqGnR90Ujywsp+udxoI8M/ZXaZV3RBTbntPLwnHaXVkOB jeJEUb0sFgBaA4oUMHJS2Hc9FjAaGaPnWpb5GpbZzbBX0ssEhljqOQTC0pgUIFAPIkaDFhJObko+ Btcdswi4wFF5Nw5sZ7MzFx0Zb97mSKb7wsVEid5xsjr3MTbpqJfIL5xnoSW0BAvN69cmXy7FcCSy LpyXa4mkJX/+eOatwtVS2ARCj11FNHVc2FfgLDSiJcCTMHq1CMYu/+TcwIIKf7ZRwF4LumWpg2mh JDac6B9S6WhSRnO4HRfTAJ/kRRlp9kBjMb95olJ7LsGzx7zah5Ge67x7+4gRs3rcNaPG9sz9XGKG HO8Wuw+rwTR6iKSNNFLd3gDOSzojDjqbAxhlONloPh0fOr/eo9NrYquNgKdjtOPnF9qosXsFRLl0 EsPBzI7fqdrkLOIeDykrE4HYJTz/9KGholEDQEI5QOzXfNywYduEOS+o375uzTPs6pIAQBEuiTrZ OT4kgCQ09iPDckRXDfvHChAcMbXxuNk1WDRJEv2dkN4JCc6imv/GRR99n210O8CxiXdlBivszfPL eBz14HzsO2G3ycsoEhwCl/6PkwXaW2msw1uNIRmlrI6LAfp4z8mwU9BTkLEMWyf0iZWxfBMYlG9A cHtDijH1hYVgwP5YPxatWlThR93MIFPZGXgOzM3vAAm4TTSFVAKul4i4uUQprXPK9ArXRbKitekx OmOaSIQW6Z0XOwP5NSEeZ3ogSU+7jOILtybyrSkio1vxzrGcaXMQFp4KeUpsM0oBaJ9mpwbX1IjI xgAiVnEuwvWJ7zDuyunVGcyNlbkbGTPOaTZ7EDZ5vfZAczYxbI1P2D60HFkjzjeE0udfCIJziHmQ rfrz4W72OfBu/R0+N+/2cRPKToi7XTDD1W4IGc0+kyDBRGIhsPWMwPOoTShmOcmlG6ISHyYAxRjM UNFNK6NjuGeE8hADsXaOZn23vOyxCzZ7YDbcPuBlYXxtXPWwtgduD4cUz4YGFp/pMpEJbILQKqB8 Cpc5CUWmgfAg2FfTUGQyLGAlAl4E9+2pnAmgsA2xQjwfYkyiii4SCLiqD182saxCepOlPNOoP7MK amhkTPCcHTKrMYoLcq1m5/WOTWmBUR9tsL9THw1kjgsUOO81VyDGGzKKkHu6NUFC82ED3d8/cLUk EnIaTKk3eRWblkO3tYFZmF6gvh6YDhvxZOLskOXvjD/W0y/XfHELewmx3Jv/R/iAy4joj/xDlphn ShYOCmQti/4MA90YlLFoYMgZ2vKFXtY2WqvEJiRnnANXUKdUg+Zt9NhCRS2mKyTd1ZK2lxW27WXx uyrLr21hXA6Wd0xWIihxZ8q1Ng3s1RhZztDL3aCBo+yKcqMLOMKaiAHYdpZ7l8luGRbDifXvCgVX KAgtC7WtjYS+FKje8rESE8RpkdL7F2a/Mj0uC1Bf+H8nxKG+dVXbtlUt7o60ZaiX6Gx5SgP84Pjx 4tItng2VTcYCYJJCmRib67WsDIx6ObOPtdi6ErrmAYXLUt6+GUcoNBj42eNotHkW0zXPUJJ0vDg2 JoHJxieT9y05MtZuOVjWrvl7vT/5m9csgIc1SaXmCgMm9Qzy80vO81n0bWTxFt6xDtyGNcByczhS Ju8rmvb59USWozo8cEm8N4+Co+TtFV8CeG5FsXp5tw8y7vSGtiSVbUrqKb5vnLYQSfRoIiRU5MaI m4HIBo1Ot3btCIxSa5aPzYH2IqQ5xfgTF6sDCEalJL2wwy6AR/a5VLBMS4LgZqv2uQ/alCuspo+F bCzzhElqgrv7QEka6JJ4AKFAkjSH4TEsx+nvwHgg0Km837gEDPkzyenY0Bxf/e6+XptM02u1OK6s aK3uChLxCkrh+NHlYVF5lipOm0uYcQRZxRG5SYPAkuhu3gFKwfjilffDcPRaHHGKaSR7RX7vYxhY 2FvZ/7mGMchw51c3wp8LaxQ1u3ZpC4qLlxsjW1sVcaBMjkhwy3MciZxhUKsZ8vW20E8CHO2o44wz AKOEMc45d7rLdWv+4AaMnPyMtrp1gmKEHT6PaDl9usucH2Px3DNq/ZbgiDjbofyrAMXGTBn0SQHs wworUFZzAbWR4aoCsCK7LxcAAwlxqM2NQ5VMEFR25HtW45+GX7Vlqhr/E0rLr9ZF2w6XAlYHHmXL I4w0ADAOJGaFLiSc6LueO+Y2UUV0li1rtSu9fE6oVwLMUcOvMXEojYBAygI1A3wUh1TSgLtV507H R+PEj92zgoE7oP6B4WCccclxOGdNqtbLfuUQT8S5IFPicETc2iWPHxvwCEC6OCPzc108Kjc35H9+ vUWBSQLby2Rua2zJ6i1hyt/1d15mNmXnWuK7JHQ9IwmeJ/bwafr+TjuP7vXfO4q0BfoZ1fOBxtXG +qsBy8btGtCsJFV2mVpG47r1YYuAzpBKO4ljOW87KL6IGxazCscn893VkCBpswptrGWB3Gb93Mk3 bya5/VC6X6Be2WsyKhsRwGi/2Ns7zBhrV5GxtUp3XKERWVzcUbfTmcXbW1uQm2kb6kt9hNIddb8x TEEqm1ZGd3z51JU0WfpTdO9g1CWvssNfP69I2VKgSPwd2BQOkbrVMa9cdqlzARAS3q9gQpB5legc QX/iItdbViDj8RkkYk5nr34dVmd31Ish9+fKC+ReXosS0B9IkzInRmdPBpGQ488z60TyCiJKJMk7 exRAziMkAmsYXQYZb5oFPFkFTwZlKanIEVi5kbgYH0p20XEZeuugMJmIC6fVj6fUWXgv9kfQi59E uDbw57GAMpU3vxSBpawRi6WmZY6ZkXGVnInMSLgSqTDAwXD4iZwjT3nNJlvPSjpW9p2fBV5+e/DN O8xYAL+/nwRV3784gL/unkFpeZjOT9d5DLHfYLnBKu0vQ3gbgSTFrlfqm5dtH3ROQsVjg7SbX93F 5C2nFC/PwzwwGBXHCE0ozrtZDNMKTB495lvv5JwA912XfkhZ1NoLeQJLxExiCJijsGCTGFtIJqEI PTiEfYBdO4jGFxh6YQ9ghSAGHHC5MwlOTkc5xbgsmjR8W+aZ+vGN1n41oTX3nNvGfoEb50+eFuwZ a7k2jxO9KidX3v1Jra0HwUsqjBVoNztMc77uLXbemgDEiieRM3aaZz3ZULPCyxEjZzjS1qenh3fV GWfvxXgbpZAybZ+Q434puJk/O9AhfNHr54D4ZMWfYbqtdrUk1VsEmZh7CvxID0hwYyW91VEXfXPJ iiOVRZ6Zu6x3QnfoD/ByhvPwaC3NNz6V1YYrB0lMyqrGevnzBw8nBdu3BaeppCp2AhufIlYr9Hgg Odcb0aVLNkTMptk8fIa8BTsk0ErZ0LtnlR6amiM1ffZATUKFs7f5Us+XaYj5R/ktkJt27qtHLViK FDV1ClTEKSFD1Pv8Dsr6DqX3mUihnwkJRgAB54K6FfGZxwp92Ps6SHuhVxkrPuhBcg5Nf809hk8a s7Ws8f4nLmDW/ovAz/eU7fECr9E3p22s4uIRJPWYrdEy0U2ox2/u1a7lzxocHP6Yf7LNJ6zUW7x6 tvPII7+m2wTt++pDFfu2lsWXJlN273DJACBTR7GlYzNWyg1pIlxCr7mAeoi6tASLP2cYu0sosgG3 5+yNdMIE9EqOGgCclehgIToLsbt89gMKo9lFORnAn5wc26ew0qbkWsLZTxKp/0GhkuOyyykpXdbQ x52H//49tpVluSxF3WWNxB+XQKF/0bft3Hdo9Q+/jW4cGwvgn6QA+gjb+SoWyAZTKINmhxWUyWBc CBxgLNqTEmcPBy6j3tzujk1SSuKEsIggiIzYGHcxmftJy0ZtIGDUB2pLAj+UptagqT52Vq+Qx5EB /zUscmrggbSfRWwBzyRo6Vm28ewfcfZXl3YppRZ0UpPsfFC2FOoUgKHKzeLWr3NLC9yPbADeB0Mf 8IoHhqvenneAD2IurKj/EVxgQhUkK2piRdHytPAaNsP3qCxDcJWkTAkTP/LGN33z4Zmc3oZQYGR6 kLUOEPMQ2AricYLmG6uzyZW9fn3sAaMljQvffZwNyDn07T9xQC0ndedPUZMPzANYdb6BLJSE8PdI 7G9b3Y6VB4V8SX94xGZ0bzIAAwYF+fVX166pXl1lDYfEPLORtoYE5I+6v4mJQ3EihEYSJmvirz5j bNZWizhOMgVeoSEaftTwMBSyiCyJC7O/6+w+M7oSdv/jjhin+X3ylmLXjUSjW/okiW3GUcks1Xgl LyT01yvGh6vfKMJH17CAMESzafFPe+Nqi6pD3zQEZf/Qc2JMrn3447doUXGS1rTpuF15aAli+b3m /BXThu6a23XLdVMmhLXThyjv7eLD4/CEt07wmNr4+8ka7ao84A7U/55Gcke9ItwQ3lCJEs3zRXRL lGqORu0Ema0sDuMalVIRRSAgvzjcdFHok9Qp+Y4CmTcD7SFPVNbXK11pOuPH5cHqUy4V8bFLamhA eiXH6izVqj+4QEIHdEsHMRX96bvLzvh0Veesw2+LtDV9ZwmZrJWvBAlGp3vej8kuMF8/H3F5raoB rr/RtW8a69t87tVPMrJtIBAD3WmCtL7HLNYEaxBBlcD6s0ld2t9p2ksNAB3MUAsWPYcz7Bu0XZ6h kAIrfxdL0Tdrz9DHWH9/kpv4CdcsA4iwCeLAeuIAv1YrMalAy02XRziATE1FmhUTdnFUKb/eXxAE CIMC/BZWrNjeeGT1pUvT40ccwo6Py1mPNG5Py1KpcL8Q/jRAf9ushqNEApkkKTmKCqK6pt2umaBP XFt770zSfJfrS4+YX9eNGG1Su0fScs3RWYXV1XYWS8qSaQ3m+Uc1DkdRpgbUpfT2iqQ8K9TQ4mZj s9zlccLvhQfXGg1cQ3m75TwzdHZSTVUFctdiR65YbVmgY2T+8+KVa6mD17SslfgR7EFaeBkdLqrx geoHJN1xQIXdCUgyhX5mCYfTRWW0owNYPMKiS0jO4bZWLk+85XBWuwRe5V2BvPTH5pNP0wqaVBd1 4a2q/WR0sk1dzJhvFBqGsjOB6iEsSCyOAjDHfjvFHmpgr7pZ1QXoZrwmydXVq27U+a5ln/1G8gaK WhbJ20gPaiudo0aN8Rtikm2iceea+k2n+MnlssbUjk+tQWiejrX6Lli+vS/g/M5LMxCEgeFqN9UF 9yxpumbMoYrb3hkdQZdIFh8QtaUisAa2lfeZD5pP1FvqprrF9QzhDIfj7071dopd+hSQoPVMtufq vIQWNC46110AejaPL+Sma44G1Vvp+Ghs6jMYdi+2bWROYzQPXk2ttWjbmEFIbAGZ3VXpoVkT2rVr AQLOC0vegKdV6qelWCem3J3H4cwEMeSpEqWh7bpa/lnz8QwTI7/OEZlN4QcWhxEj6NE9Xu1GVcNq SnoaWXXBTS0SBurDNENrc+ZCs5KqcXQOowVMJOTgfTMNw43k3C9ugRmtkbYh+mYAi9bx9dbHrfNL Vu5cDroQ7oGZaC9vWpCXwZ4LiIhZYHQkW5Z8QKu2hAU0KDiq4FRcTlV4TiCb1mAfb99AyOOtCdcm 2KTY0tQBDWHbjh5UhdKFC4e0M8xjO42kNBsF0DfDWXC/dxgwhyCKbcqob7EbCwshIyERS2JioCIJ zt09C7RjF4sh6yI7K/xB6e4OvK97uffl97swprKSQycSWKpoiLuvyms47vWikd7l1V2cSmjmSygV Wv6ymZf5ZMKmcvntsgzN9WRiMmsi95aJsPBFd4meGQOWwtg/4MXA8DNoGD2bDphgHEQg++YZgCSp kZGt9FwEgpUJNHPRYOE1mBV7tnd11TxghwPBIawV8J4B0Zxq1ypEF6qDabxKg4sr/aZuAvWcYzOB +D81wM0Du9Lk5cXQXtX5SvtXll8JLoEPqiUuAnFELFfJr0xhdh3T3p8T4tNjuU4EF0EYZ3UZ/FJw t07az6Yn6YgtMxEd337Gcx3zWhkwz2JWlkypocmWSNmpMG5aqRRhbBZdxZKnsNDTjU7CyDfwlob4 K1QZ1YHQoiJ0lnb9ScMxsa0NWmIYysHPb6spcEMwNvluxSJJI3v+bg7682bJoJEfjS3xyfIRcZtc uBYsRv9YT3fPOgs+07t+4tZzRdHOijW/X5UJQQGQKdE44rD4jOHy1ut7tsT40JPwZ32z2HFAXFjY s9+JKhMmEvQKBcVe8r/A3gPlN+eDrDo3HVk2H+NgFk/1HrQ3IwXpkz1e25ED86g0o6p2EmivUje/ sf/YIHCcsHSwV9g0Uh3VFKfoJdPog1meBps7t6pJ+s4tXar//l0X0WB9yfWpSZSj2sSJm1HCdbRX Gvk5TlqWmt9RX9bukYPCmDGPU0G1sa/sYuz4BuQwv5xEB7M4I3O8fXQH5S/CKEgSAmM7xQZqTmS6 KM3Y58sbEbM1FSew0wcjEAnaUAEnU+Aq2uaeZZwmSnfOIfdE2zlbp1FwzFXezF9vPC8+sEZ1KcI6 iWYjhVRIQPuZk10BCNTPGw2I1Q60/Sjry6OivsXe3gFMjoQHsAwIUzXSkj0aewAIgAEcA7i3dTA2 0WGeXXAupVP3F1SxiEGR+SwrfiBtf7I50RV0puJNeHsSPbKc+hY5ZRHPJaSZYNphnTjDQXcv78bl k8XDFvbe08q+aARd/VMqy5487RI17S75jO5uliCih5TCRATM9WZ4S8qdpKVlZjCsTBoDoCPvbx6y LdpiM9tjHvh0e0cOZO18NzXcxHpdMXpoogKutBBC5dbChbKkQF71SMq+cwZV3BWHD7d2p+QWoVQu XhU58WkG4Mjv30yXR5PZ6uPePr7//wz/OZebu3fw6qVd/fX0gk399ep5GbhmLREGOjwzPTriHdSO YLBfa1RNgsIrxaZsf76vJibN6Txm078h5UHzNmXclGBFjdyvRSrSkFKMOtLNFH7/0MAArd2MONz+ 76TjOTnJM2uWnH7ERiuA7GQfIEcTh9a8DOQO/J26qkZENPiM9HHHzbRY5nSORuU55riia/6Kdrpd zcGF6s5Lh2Q2Vt+eVsGeK5AYCB4lZBlgfPkS+TNEWlSS4pkQmKF/SZbkmT2r46RJvDfONa6XRasY XC98fQsUTA4DYPJIWb66Oeq5H+CICObl/ToXuNIYZ0+Uaycd72j/QqV6QWmB0duYVIBBjKHNW0vK y8tWeFquZBDsXPoZNH3UrR2NJi6tO26hDVynfpMwJAaGQD+6eeTgwQM3HwFUkar4+G0XhhySrfhE CyRwduDj9+tHH3uUYfs5JR58Yms+2gp0+nIqHZ4gj7R2jgz8VNLnVSF0ZTzcCvOVmIzvwQ7J02F5 0XgjGdH8VdL5NQ6zjAdZNgZrTBU0wqAEUetTdmnXJS36Hk1hDw522FYJrKstgWgwx0aQEyPJCO6J m5XH7Q6VyACzA8iE0MK4zNH4o4hKNAtilABi4y62GP+g2t1JkqAcit3O+9I1+hp+3LiC3Foz6oeq yGgNGO3iffHYGDMkSZ2Y4jl0tN4f3l+zEEo8sv/dld4DktCFoa4deizHFR3e05HhzqV2CwckvVfe zUuOHLKr2z92H9cY+bilHV1XWjt168udHStPBas/pXeQfF/iKrWmx8ayadTOhrNaXzFLfF/lwu48 MecI5axUcqRqRQMW5QPpiflL1uZujzMF52k5rJqOIVerbgJrnlMGzj6uI4J+Pmf5EuanJz5Nqzpq GanVS1OBIewb9gSN9tYsEnFMAjtUf7ceysPLfUx9Y2Pp1q5SyX0yeNOESWhN/HLXa52xcs0Jieek x6WawkDVHm1f5Gm34yp9354R0Av3CMhCe5l6bowiVLtuoDqVUb+po97n2UdXX8kpHuhn2/Bos6xC a85+nwTEpOAxzdM95vXb3vmfg+N9Rj3/DDZDJAiCVtFrVymlrgMeSY4e+WHBX2LZXhXFAFQKnlgb 1cE4FjN9/ju28uEH3+8z48qyBBLfm/9C2kDLpr6DvWbnr12Tu/22ToHODST3gMnNIEnKIikLxdTx ciMOoPFadJtSzP4r/R47CxKVYerrkaQMlDLpC7svFAQ99XVXJvmLPwf3oxwrD1ObwjwLysqFRSPb uwA4M/aslk0CjTcGhC/BW+W8uhWb/sFD/p+S8AVpXNDj8PuDcH6rYYRnkmOmVccBcQeK9efhY90Y ZjwyooN/omHk5wMEfp3HDv9gRM11rNyfeH6us5UY/p3R8n+393JCXmD1GM5s9R+3ppwgJV/PZPWP W5g8+/tVQnVHLIVC/QIAxY935UZQQibbo5JrP7cdDY3Sa7iBH1oaAyW/IUN4FgxkTS7ELJSdiPeY Yr/4PixuC81FwF45e1S6ZHubpsEQlxEmEx6+E+bsjFwkLFIR5rHZIl7brEkSxHbBQ5NK9nmjoTYd 4EQ+zPyD6vH5/8vpsTS6xu+caPDx2P+qvB8w/rUe6JKZLuAf77HenT6VyDJd138S/yACf7YfYh6h ZNR6ar8MwMshPs5kmJnoodnj32IJ9W8Es1r1JDY9i2RfSAn/cLsML+4VJa3KA/Hu3qvb4oFZtl3A ecgPKDdPYxLCh+GtLU+cMFHiPTDzjsR9FfaF+hAzCG+hBZTpLCGNvSJ5MUjQsiYZ4DMw44iU/zE1 iIhjy+zRV/a4elDHK4Yt4bLHO9LDfRGClQW2zF6mDM53Lr/O/IiHqPmO9nADahhMz5nICWNDBFAM HmpjBFuc6Lx1gp0F9YoJz0Jmn7VEmMuAatgJEQK0J8DAMA4kbYP8bQFERuaV4toUHtVmWaoNTjPl WeWAudUzMNB7kto3Cu6YEBQpJi6QinRIcx5NRO09kq1kvbLINEJ4EpV4c3MY4dLIL4u9DWwA+ToK jrqx4LL5wFIOzgMtRua3/GNGWCvaEmbCZtPCbQFwj2x/+8qoefx0M+54WzxruefwE9FTRbTzgtEd gkrY20xJv+v9MUGCKAfKbn+6cWMHiZ5b2H8SYW7DNh5XSCPc7+KjacKON+sWEqJzuzWzj//h/OFu gKuQ5E24fNnqKWklNsIidVkU4VghTcEzvKqlM5WUd8UHRh5LHvuX/1k3vWDRQMlQlvDBMEbf7t8I +5MzMqhjmqJAPesuxHGpQSTOO1woCo68uYSGMA/tQEDDPkA8+nmaukF//xWdJoBOGVRrcs33SJNr lWkeP8scjOXuEjSSnuCLCyCOpuBZtSukpeKEzEZjf8saKzJdjmYwe9XQL+OMNOZ+IkmHVVeLAbK4 eYbMSETyyXDMfEyg+uyE22YGl4qlK/Lqp+Ch83pdGXI03b3GimdpPF+bj64ApAqZYOHq1QVBwBPO /5v9tbglMDGb1r6DHznWVoKFy1d2WPod6es9dPSl6roLAt9LBj4y3CYNeAxyOn9hfYqUDg2GS2vr pIlXr5j1DUq5ss+rr5XJrl8d0VuJALVCNzY7OyE7sgX5Ny+8V+7obPNHrPWdFWCP2yrvODWzozS/ z8CcuQZUrUmRSarmAkNBwHoSS0fvlxFQkc4HF9vRcVvOYQQv737dYgsgJk2XdotZSP934X5z2oxW eh6PvLejsZCqw9+QGgemrpQS2yIGu6KEyTLzWmRA6ioJKhiS0d1WnqtRO/tT9w5VUVuEhJi50DjA 369wXWJC92BThJQgvdiB0hv2ukLq3tbbBMR5rfSJwny/P9jzwKEtNDzVLcc/m/MEnw0VvXrupvvn vOq470qrsZRoCy7sdrBwjPNESQgHfn6jYj2R6qXL20onVJ1IuviJeMwJItNSTIYmOojToEDrOu5M WMrRhb4qS4qvI14j4Ch9Y/XTVgGB+k1a85kEd/IkI6oFAEwrPNv0ddo5oEyGKjZsqOjMzsYP65eU rZ+4/3BiRVlZWvqYJf4S3mo4KSNBkFcwuDovn8/Htxl8CJfJZKD0o0q1FucqZ2J7hoc/uId4SzPH u9jw8nJp0jWVKjsTMPQcURBdfzKs/TDNcewr7u4iyKSVTpNUP0cFH0ecHBhSYxRSxS4wcjhXoNaa mpJJTVMXiZFvV7wwZgL9O1X8Dv1Kbyqohh2u37Gwp1axvmrVgcYF4qJUSQGVGqVEuzJ3moA5JkM1 eJqLBwQvw+vGsWCpMCmjIpDMhUjH8mS2hBCZnEC1emfkdIke4p/oVpEcFcNNl7LD6eGSYIaTqdYj YyXFbxcWiY3Mx1lluii70B+YElhCSwZY/M7mgpGMU01OIkfKXSJ1rSnuAgDIhT4h3VcQqk442KFt b4aL5hGpqCLz1YYhmFoPW95OmdGUw4ivMqW+gh5Dc03yo9L8HyJ3PBkkje2477u5ZVmkUkFO1mca O1hkxyGIyA1lYnQvv/9tFRZTwLJCkG1yIY+Z3Oe+grOrp9f6gTyMgH75HSNSzHEBYMZMXgqNmTSO JbQhOdFh0HLYNZebGHeD/bJYv6uVGCQS7LFyQNTZCK0WY4TJOQrn8vHfUc4GZPWoyDgV24eIcoMr uLaT6ZDrEHnkFQM+tApNiMLoOV/UqM2jPjBM+KgyTDXiBLkIG7DcG/SL5rkUsIrYQ+vnBVcLyTwP PqUaF7JceMy0KSq3+RJUJV4McpEJljuHihFSrEXaZHOly7PFhmGt2x094jFN2qEhZ07UKgKAd/KC l1dB3hD433FCijONCTPj3GnkP68sdDDT1VHflCl56mAn3RWJpjNcL57PVlkS+zBtBtDP7Mp6Lwh6 HbAR037iRBcmFBoOGxF1dhKwucD2PnROA2simg1SaxCmmYDesa3GPY399REIr06zK5msVvxmPDnJ DmZTYaXSi/tUaZ57TBqR1RA055TvEld3pCv705Ky6guPmxblH4xuTklpDOhQakUbBO6/aqknKQqY TfzQjTvbhzasbtrU/j7fkxv9sIxbSU1ihZOoonh5qZxryJpCMGF5l+P/b/htqiQc1m10Sb0bWYNW NgTu9tFGxh58xnsW6b2+vvYgp0B7IKoxJbk+oF2RlzAucD/r5zkuU0CZsUuuTc8MrlvZsKH1bZ4H N/rXUm4lRcEKI4IOcYklMk5Z5gaHbPzYPtxygOjwKow8r/0Bf/p7JC4iu2vVOWDT0y5lZxRmr56c mY1vgsm1F6aSKotLnBJSItuzPenk7cXXtqqoh24M4spPntThrAwIKTXoduXYmaPzyvY03KirufOf gp5cnawnOFlFU7oJwye/7z7hhKfcmroJ1ADLkVMbFsv6uwJFI2egWN3c827L/sCGJuGaBgIZ/tHh 7tgDvWzDrm5CVZXlqyS3KQBVvAR38hhnR0CXA6CIH/eu+zwH8IPLtIgqA1CGnZNfw4FJjcGgseJE X2MfBurDL0/e+qEbFH6se0dM6p382oY9GdJI64Flyo1ReZTEzLXk/rEiq5sVUmVPgEDEE/Yid2+s ZT9qtZKHZPZzwmvgCdI1spCdJ8OMIBCjsJNbZCFr4inyd0YPCvsoCeEaYSgzLj8hHbC/sXjGfybZ AeCclpkIDU/P5PLy1Fuz1ZzfPV24xPzQagUlUUXbRfDnQhZ9wuH8eqDSMZ/IPFPK7NUnB0WlyRi4 j6edjgMFbfmmVe3dS3Gf8zkZt7OrxtHtP2s/i0nt6q6utmzQ5eXYlvSPp2sFlDwEkFR5hZRQhrwS /RR2zM3Vr3skeESgO352LbEz5x3h7No0SBvFCCoXCgRWHQ1xO37h/Moz/2LSj4uQIOm6MSEB1Vdf vzy36Q5ikLwCFqCfMUwoztxQEf6pzmlK3un6Sy7xB9IF/9kFhnSP8btD7D4GBJamWqHEEy95PdM8 uT0Uo+6HNp7KccDTZuUD5KGFAZ8+8hcWAQg5dYDxom5pWs+Nt90lfZca/BRhGJVRiq14KL4+f0uH ysTzEpy2taTiM2wN547AzbNfGrY5Yl79TIE0oBOZZY/uzZLmr1VFqp1xMtK+o35Cq4BhCH0JltTX aYfdtPC2r3HPRqwx7WJk6p5MvtRBZMQF0ozZ2ZZzTHgvHCVFRwhWZ+BNiRdM2eh+17hyPIc0SjD1 23StK7UcTgJlgwh1Yp16EpBUt8JIMrC0iUaYErwPREFPqRKC6Gsw5lTNPeHCoBx5aYQzDL1ECB8r DgZ1ABNjG8Oo4s7m00mTBNtJR3rubDW3q1q3iIicphouI0Zpa3UAheFgEBCbvf/wkW0nutEhM31r nrC7IXM9ab1Bg2m+E3kZVblNNseqXG4412cdELC8iRquil3JJEQXJ/DjACwOhMDYWjJwVsJ8B+JB SpTG4gVMEDiqhpKEFUE9AEJiObn0hHW9I9pRy55nCooGcFKlzxnPK1t047tXOLxz8u7ptCBeOeMY 8lRIFokzjCHbDY7nLxFN5US8cyBXuPEns0rGs5N2DJQcAk8oEBKtCbJi6YwGwAK9ZLOS0oXBUu0g 3F4wtWYu2kqMYx1djkssNaOlKXOLZlYbFdueoupy6UrOGNffrmfdYmPX/QonV6s7GIVudev3iVPd RLCqxXRrhliOe4hpia07tEQ/7Pp/1b8CaJqmusHuRi7ECTDM67mrXSuyU+jWEarL/d7ZcawROHEc K73tsldfUzYLzr54EIcr+XsAKdkd8D2ugzPU8FFnMKqnzEFYJh4uo1tnx0dXcFcb1pNhd2bhIJn+ yG/cFmk8qxaduPn3nbawAkfs3Hxr1a//aKNmUY1tL310n5Z0/rCdHWd2XenL8jM7dnoYffs8Wtpu WVja/tl9a1W73erfb55y4jFh9pLTDt+gOcIQstkwMaL8Mho8qTjdYSM5adzi/rCMEfUt61aLqr90 c0IXNp4ow9ZxgrzxJ7tKZ7ySKR6wD+Gx/K5OciZxsR0vpuUcKt5U1aPnpllFvD+WDsCGqLgT5WM6 2NzVtZmaRUP8t8iq/JQMW5Tt6CzpblXWneoeDNGOMdgbpiXgFH9j+3fSN95P8onlsuYcx46FoCiY nROYPHYwm1f5pry0J/ucQmrMERBDRnBnFksQtsi7PLrHcE56IIaTx0o89ImFseCtnrAxzZyBnuqB s+hNC2B2yaMBs6RCN7nwwUgPYpdoVBOS7zI2Mc5k8ucQh8yMD7ZRxPiM6PP2VDTT8SC7CSfh8A5j EThxc5EMy4c0EJmeU1jXPLmmqaypJh+HQRjH3TvUc0kKnN/dz4DjTV2ATVLd8EkbnkfKT65rDncE zOnDOyRVH2Z1mzNNJIlL9MfId+Pp0KiAmcnQ7jSgkTgD4hYhIcumx3D/WfUMZQTpnomFXhZxWDnt Q78Eczcq7sOMEcYYY1NTO0EYQHGvOgygWwHpLIO00aemXCxi8VgAvf7DO17fK7Mq7jEB+qhdwcM/ 8LCIxWMCvuIPmPB6kSF/HwH6yOJQ/IRGBx8DyiRbNoJRkRP6sLaHMqy3u/g/K7L8CdZ/3UN42LaI /px1E3N914q8FQumGYc5Jxq2dVzjl+7spl2kn3o8ElBnsYhJOAboTy24/Wa4+9OHXab4SAPXM3rW X/bv06JcOkJmCg0L8vHuSTt3YEoqZfeLAUSrxidMKV1u0IWWlopBcjGnsaWkSHjqQh5Cl7wekihA 7OwXAODhkxuPPyjMk7JIA1bPs4Hi93WxjvlWc2WTaUx0q8wav5fF0j+3p6dvayJTBE3KBUPJpH4t C5PaWhPzWDQlpbW2JeUturabCLElWibG1y1w8Xl6IGcOkX/mpAwUSLjSOZcz4VmZmlhGGjVdh0ob Q9OBM/hG4uJUn6QD6E8XO8o86JEA6uQUS2VG7P6G2u6ZSv8xMstwi3mGyIHVFV+dRGlN5Q0GdWDC N0gDFpvpfyrdjN51jwYLQWvpEHmRs1o/MVhvtI7YLej0zE/Hgp711953rmBIYivDcwumEwpkQ7hN A00sbdi0sPD5rZ2nxIjbJoCapUWakw4gST5N7WtabdHS+emeJFCQYrXRouB5HXKukmrdd0AUdugB YLIB9XEkn3PbvVglG5j2esArWDOoooPYDFhOcnLRKdk+/SNg7bzsVXu+/x+AuOrmtZ0va2ii1qxt AjJIzV/uC75fS7hw7nYh8Mx3mza9y4SDJmS+16R6Lr2Gg7N2imsXuP+Fufl129CC2uNeGs7pB1HH EfemSPyTYGA82O1nAxEyqXt2EssoD+lI84Iy3GYM9EwOah/CvMgmuIVuGujPUyMQwKL/aBiXVJdd 0nG9glA8ShTcLsBBw8A9LH+8ozhtVGxln7xsPKfLAQBdCUxHCWHSFt6hyssM0Iq3ORtSuqWf0u1n nDK2vlwQ863sWKQam8bV5h0/6FrrRyg391/8Ug0f8GXR33NeoQn7mo2kPygfSmLijn/ydi01jskz jEmOfkOcJ2rOvjB/zlVYrfSYtuCWnPIsdZKK6w+VprZ/evwcIEJpk7txFzIOXEnZuef0Zr0bFUd+ LvIaPLf/TflA0JKjH63unJHPrcGD5vupDkOPSHm7owskfqRjPQ61W4yPxPNPqWCTU/2WTPnHKKXB yRWmz2iMQZu6MZVcP4D20grFsYYZXolmDnKUR8GuGyfPx8pprRzyeSWgf8mnZ5vICImOaI7ZvWrw +a2e2uXmscaqUdK4L7UMZcxuowf0D6yRsqaDxy3/ok/ReMR4YXLDFsCrpYN/0glUg/sr5Ge2ec64 Z6Hk34hTYTaBiQ7IQr6pkOCQKHt1LlPP8A1Rri4cgDlPBZRXTAuMgByfd72Rm9CgDB0wbhQthurO 4J1tP+SAoLmIBXpvabiMA62ulmm2oym1ikZ8/3MUM9rB6P7xXYZZBdyNxFXfbljzftl+mM1Peq2K SEjaDzGdWaD0XmGl50s9mYx5cZKETEBYxCJq3/ovcdluapkjnzuWj0gAwcAh/bl0KQa9YarIIo7u mhCBrNXkvubJjIzAgFD2ZHVf9bDCBAbtIwGB3BEG7OgAz0qwRX7kMkJEMrk2HRrSNU4TuukTF6Pa c/wqLe54zNxRB12zZm5uAy1KgwMnjT7jq/DiTLqzndzS81jko5krImR0ZDP+M05FCpY1DAXhdtBD A9KkcdQtfuy460TLs6vnXwyaP2FmH7oyriVbsga4IQ8dJ54A6krgRNm5Th+exUqslZaD5aGzBgr4 Q54hnecMMhVLpoFVFG8GyGCCKPzM+l8r/qupDYQ1978c+Q1drzvFmcd1bCD3PCUxCZygroO71R8X bqs/bH6R/9u6K9AAd1tQnB9ES44X2sZ5+ExaEn6+l5KTOiKQgvklndXZUfh0/xilK9+qkP0m1O+K d3cejBgbyNVEYFEWGkObRcuO5iojeC8whOgBvE+liaSnhryuKDg49gjA59VnFToJzpq9YUmFIn8O 5yclx7tkvq/7WiSCOk5sxmsMhJ4ySbQ3jt6N41iK8pMkiVUp0kBXkew+NfhXRahqtUOLsuUUBAGF gOwzFfv7p6EqlParLfq+jCmyllakyMWFSSJ/HKcbR7eIlkniwJfMp1BIsApqNJgi9jpui14FD2EG SuOrAI6S6R7xWHeM2sG0wWsD7XeMfFgPF2YD5Q35xc1lkhBj0P/QSpsB6zkZOf55xWj+jqw+N22O gbxls7M0RaUOLzrgbvuMQMTmWxYqf/wYw4yFSTR3kNetf00dNUVFgB8FytpcBTCkTLdYWhmf7vd2 Hxo2ARQTtmW1dtXpJE0c7p8HXQ7+8FtQ4AQ3bto2RTr0An2UBHQEa7Tdc8RRUrI5jK6btUHDJmuw CILfZGPUGhAxX2kJZx9LmbqJAk47Fz2wvRybvl8i2IL527JcS9nkUiHLLZZrHwkV4M/nQ/b5hUby ZKCWUd4dRCsBT4Lm8VhoMbXyWAoWjq7cD6RoWg41dxz0v9cU7N0XKipX2dWzHmhn0g3QG+YuyyPt HB3tEtnG2PY56K4Z7fIvtXaqUpF44WjEKiOsCBRX/rf632ALc9nZY+Mu29EnDwRDs6k07lKf77lz 4hiOO8fyBIi6tnD4PhOuUkA/D0ZfxI5blZzaKyvtYuLc9UXMuo3cC6dnIc4wL23j7zv82nvcpMdU Lyu5/Fm3zuK2zQuxz6E8P0U8I7Hs2k6xz0+HQ7LSwtzbsbvPTq9bJfpmhXwqbgogHQ3JCACx1jGc Wuxskj7p/i5Da8efjyul89F+RyxO7Aex8Bdf0hHZGjU6shyOWZqYVt3Xt+4SgJAtuqzhpc7oJ9Do VF3Zp/R0Wsq3xhG7zsErzat7vStZRBiaZbWD09DWbQOkb/NpKdnZE3Oizt4ATQEm8zOwoPkAUxmF Yx8QAOUbBqs4ykYStEsdsa3ESGy7c3NDuTW246j9Ls3xdWcH6IdOQRzxMx4sd6gp3e5h+dLX9zX6 hthKh4FMDhvev28+hsb/KBAvQMOHM93mXr2aM80dhl/rGMaIEiYvGqdeu5aKvIhGfj/T4Q2E3y8T ZdqmPG1wx+V/nlLU9gzyuvFPBOENALWHu9BSuyQ/H0fEMcjq5axR+xa77O9WFTKammpqoVxNY9Mv F7W/U69ubNRXNDXqCEihYhTEol45cnbi3DbbFvo0hTUOKFlNWb2W7DcPqyxKefmJiWOdeFC3KEDB V0j1lHj7ONJ2AGpAYoXDpkwKPLnbIZYVRmMMqZNZbxo7drmpEex8d/eQC+aWqlMILnVE9uih8Yc3 Dw2Jo9SaqJsHHgAcB7i6d8G7WcJKbBRUM4kSvbCnMaFqZVugmd1yycpY/93ixRT7IEHhQM6flHLO 0o0vfmpXiooG4hvqY01JwGTVKV6rlzo5UsWuM8jwOLju0TKcXnisb2BmbvXt9cKV41Zluy0ZFiex ePTdy1r/gxEluC3PmYog5jOTYNiXp9uWSE9a0azsQItsoQKdYO2EaKnxsPTnZLdPO+0AddsNld6e RBhypWLTSekrM+zngWE9Xh2T/kKa3aZPPOwKpzgOvMRttD6wWhZ22qJyDZyUSnqbBPd6kDIpphTe noIWSscSsGVzLk1xUzM3m5WA3tQVHxSw0SbtpD3+mbh11WNs81mtQ+k0vneZrUO5n/MbLlR5ETfe JXQoZbhZNNlVXmjX2oY/3636HS8/deYQoBxfXGxNwB4WmCWR+6dqVdZETFMn/5SZzT8enjwwOL/T sS6ruWfx+KhqXOUZLM9OF9xzsDLDNjEqdqhbcRBDxK7CEkGcmWr4/ION9D1YArYNP3Pb5aa11iIb uqjTG/40qzX/y9MegCxJa3FiW0hq5SKXm/IQv4jE4lNBnLdy6647nXiuZc/Jq+uZB8abk21YAnai Jc+Dxj7CkkN2hQ42L12/iMtMexhNDVBVyRkYiyX+PNytx/RKVUiuKs4LpCtBFDcgD0vAbqD239i1 kbR1h3nuTG+p/Rl8r0PJscvtGG2YWUqaJ6PsJZutCVgk33KXshu9BHPLY0ys6l+/Q0j9OJB639xZ /Nkak+1rZUfJZTn53pLJ9foJ29OkwVsbLLwUQ35KzYnpMvuThImFJVG028A/B2uG4URxQHk27Y/J AepozbmGugJwUZZXMtn639efEiv/ISJofnMemPWWfXLWYJ2tlJnBJWqZrZBkG58DkIWhARP+gQAc ocs34/Rcd/3KXgb7bAwUWm8KDYCQsqiiLVi9pYde634SWW+uztY4TtA0azU318nroDD0sewbZ7h8 O1u/6CtHYawyYf04vpvBjtNo1EyTaKZpUjXFaRo2phs/Phqcoix98fSa6XdJCQHnWwPy4EBApbNu 0LIT6SMqDGLqQpopEtjcdX9DB76PLBN9gd0500PF4RV9CLEhC60MLN18G4Dcl+yvMIjg+8j3YOMa U41brPpaGvfeLh/HhRgjUTBEP1y/h0eHwmWoGYObtqyfHo32h+gcxLgMMBk9Tw5Phe7bGh3vCoAa /DP94dDQw5tKFlNrWN8hmGJTFQe5f6D3Kc6gdP9Cro3OztTFlyTtA/BWafeyHxxlweHmkFR3D/iT abOhaSjNxj0MjN6QjYzPqgRs+U0dX4bY274BBtXBdhLflFe/dE4uQSofb4JONVD+rrIyb8jDFgSE 9H/F9wkocC/weTm46j6A1xrIe2LzmL8/15twDA8IItEe+XUbYdd1DwZ4osK6oQKwEI4c+0zyIhLR eUUCIgBJZwMCsOv3ZKY00DOPlWJs/OmN1L9VQGLwRKrMJRPjuGUcPiOc6ZgZdYS/Eb13ineqdi4K kVTimV5Pqqg+ZS++CnwSMyptoqE+oc5BBS19mfn9g4UN08eYIRU3y9bP6ekh8ND8+cgHYVEn5+v6 gMS64z0YHy/F8oxX/2J5aCwdxdHIlQPL3edd1pmJVQxjTOJY9cSMraYg85fT/gAmuugdGxrwQM/y VYZ+sStDym+GcAMJtGVuCoaAXm+FHYjEtNCJLaWachtlNIBc1tyRNbsgxmFCOOSPkNddGBrPlm+N 9L5X7mmfUFoOIGCTgRXSZ2BPQRIgbC1PsI/T3bZAOdgJeI5WXS8hH9XkEAyOsLA5q7t9GQGgL7Zp f/aVtxCdWhiJPdh6KwFdwRg3pREE3HaINMCVoV+c8QZt8gDKZwPRJa+Xi1yRy7NzBObhTQocgSaO ee0TOsObSWDNNZXS/YosPHpTfHA0LA2CxZKTafElfcScA/6eplzle+XKv7iWRzL+PWjGZHrvXe9I POfv3uIecy5rLT9G0EIl4ByTISgKyuiry6gYFK+XgOTvO2yly6gxm9uwZNKQ3i2LGScpts6RZCMg eXM7lgfPGhl5Xc3XjkBO5vNFpyWngyvdU7Nweesu+rNrGmMEpx0IWwJjrC/ItYSwc/67yfQyunMG 2QYHoeHpFt6STVivlT/0nu7zN3YH97aS7yC3lRv5SpQhKUJGfKx6SWFGVEZudA47+UNc7QNjWy8o uyCuM6xmdwg+bUv6Ob8OEyfRlrtxQ8n48/YRxp1hUqsEsVO2WQgzZr9GtDmLzsg6INolOpvmzSFi Ahx9YCeuM6OZt3yir214Q9fdiwlZfZj8ytZeHSu6RC/9oL/K1kOkRaQ1/27CKwebVd1nk4HD+Am7 uXnGsjyW8R7vPZIDNCZdelC8R3xASmfSDiRIfk+NFIpCzlaJexJKPSAWROdf6oF3RObgn3t28T5R wob+OwYBMfXgtkVGnwTrPaYy9mw2g62DhGRND6ygfrJqDC92x9r1dfO/UEHADRik/oGcNU+szy9r vAc5E7dw1XzEEZYnQRdWiFwwxa27A4E/EmHniYXz+2D3IaPXtffayqSSCf435qRPCRCejgf5aUO+ W2QwV09CCrFrsDKcOjebZfKQ1mpANi+9HmKMDLsGkm9TEOBkHvfBXm7ym5f0uEnRay4EAPmIW9Sn kjtDAdDFxgHf7jTJD3YSTPhjrAT7ykthYq9boKwEcy0MIG5TZyyN6+KWgGHcbckGu97+81rs+Ho6 rfdOuGLAYk9mfS4wbtaqv+6hTqs6AO7LlDHsxB+HNLOm1S+fbxvDSIKob2XzeutOwKZWR2IvkPgB YTuxkfBqF9eDBaQcuhobuSWMH2B3KRJbDe/uMoAoUdx+Ca40uPr0+XUzJfwCgJBQU8KVkHAW6JDd Ok7TsXMNDdu4PXUKFsDD+s45DDk+Sb6w0w8yWTNh/gffQlD6L2ubK/kitYvEWBIaxkHlFSGs8k6X pga+86+GqmDxffpUk3i9mqHnNW5szrweR2iL33r3s9P9BI5273OTX41f++7/Z9Io/UMNNgOtsOaI 5XbXhGehefh7PiSJ2TcRTcU6k0J73O/8pN9b8pdFxH6nrZGvg3bNgv/qc73/YvQWvws855/u2MK5 QK6nz+r7Wl5hNnn9Mt92gVDP9VOMBJP5X63AWOiItcSWNA20N+fJSFwPE3lMcZtFbgJUgY9QnvQ2 7Qs7GE2k0XN3ryNtIx2MpjnST9xG3zmNu2kGd6JFftdbp34+njs6lXuQ7zT2UigexfxtuzPN1hXE 5raeb0asK8be87JmNKGSzDJWh8aZKCm95hcj4OURyEs5IfvsoMa74xufPyeGmvMd0n/xyOC66F3a 9rgkoBFbnEsThDXYGjfsttu+9PJoelpoCUkRCM+Cf9smvPr6wWl68hvN9XMQBEyFf/ShPe74iM6l Rn2QE4D1F1ODAJpcosmQ0x23NK5yDdBF568DsyAqsMIO4xUa6Hv9be776+naMSvscJr+elkjiunk nEDoNEnX0d7ZclAmZyHXU/2nT1+lzfzhK0A9ByiSTdpOWKTzMaCsoPIaIxoNZ3QOKSw5i+opZovN CKMD0D74lxdlvaX9O9VaVw0TF5xplmvGrkoHCZQEBQ5MKm/sPkf4VhvnwmPyPkSF8WhG0AH/Qm7B Hj+oHRSOAnf/b7/kEbz9Rf8mRy20gxg1V786an8Rpnc5cJ1mYvN68IyCvUDVqMJpjRdftVqw2m09 G70QuPupneqz3Yhw2TbgqfWCS3veaQ5ZB2BH4BlPuCwc2TqQF6E/VbG8KlrnO7Eaiw6dy/dty/C/ I1HOLDy3t2B1wW7UqAwdtbL//yjgPy9zshUuQ6I5iASM/Ye+2kbvnK34SJDrpcmV4G1coUYkOAxG cJRk2Wq8tFahLuapyE74mF+xpw4bvRKrW5/5/B1Qd/+KALdTF4FHHpKFMhLRDlypebY1tEwiM9Cc qUs3mbJOyhBBes2xXwtMCPU4SHtjE8/UTD4xec7Uugub2pcSNamHhiI8SwjRMFjywoY84Cp34F70 ih2hTzX48Q2f1Ku2KAJW7nTkmLbt7G+OHoTB/q0YAKlDodtiz9Cg5MiILVnn2ceDyckJvA0ZflA9 +qOrlnST3OCZWiSQu6SG8X+8caoIlHiCtjkBekLETGv7P9uX15tHbgjv8ejO12MgXJc1N6pwzVhr 38yZg0xTiqI1DcShdSwUQguJjXvKhStYQkOLr1bs7WEtZmS2udDcArbquNEKaISim6lAeDxZQjKs 3DWDGtjHvpGJR9x2g81zfgdlnjX7aGAIDLKHjZJJ4VX3ywDihnmVCzmJmluhpq+X6KQZ3KM2mcgw WtEg4sZEtB0faj/h40zxm5tc7f7d/I/T5hLeGg+FIW5sALb0fhTMYKqUg+LIfvcirrxCtz8cQDLH mSltsY4kA823Kt0dxKStnTVHgk4D1cd/V3JPbXAONUIzZ1LneeVGedPFxYtuo0phpyHJ4vqQgBw5 mO8S063aCFfCkznVZmVp2oKk61hFiZGP0VTvyjVJCMQMsfcBOTEJKfth501sNJA5s+LgJeOn1TTq tz3af83ZflCf+9hb79f92QaAeFl+TgWg2e+Rw4ImRecqjuDNvsE3zR5Dsh8RiXnG2PkxSyGxYUl9 6zqS6unpAjwq72bVdN2abtnJL6wlwrjFjzfJ500VHwQvi/yHX9j/XggBBLfNr/4VmGDburHstope p2KRFp49fQR93bsD9LrQpDyXRjXDud3SfgWXKID5KKG7vbfe6a25sGrO2d+r8x6IfKSDykCBkXm2 0c97x1i/EYQ9gXSjMofDjNB+28jS2NlgtUrvVuJFK+LGeaf4keXc473myZT0r358kYgqFrMsR1mu 4YHBaV9bt/t1eJV4UysL+pnKyhqzRQIbv18W+41Z7GcTGKJphf1uBuKbg71O+eyw/8noKVmoF8VR 5T42+0R9KHRouSR5SfFxlTMDXBOZKUTMy/fWnMDWuCi8PDJ1i52HDaajeupFrNp4f6YAMNrozE+W 1qoo+ZR8g6dUfFyUoBHIGQIZltT8QWZ6bKFOJ4EHZAjDTmjdVSxmBTUCwqUnibbtP0b6iFj3Ij6E Kg+Z3DFEpXzItk8d7bbPIi+ImWa7/jUXTSvQGDQWXcUfMTDNwclMYV8EoJKN0wGbatnAmDRNSd+Q XZPtAZkaHptkAFrvfsXd/4bwoW+S7nxH+JmoPtREAacanGPJkQ3Ho0D3IxMVnvudaegrxnsucGkS 9SZ+emRkOv4NgJBhHzKKiPHfzFNEiIuv73qm7/prFLs+8OZJN19fRIR7qr7Fy7o+wRO7RQ4esAvX uzCk+wS7gITC6ySXQ477dzkemsxe85P7/2H3GknjIzUOQGstTiddqP2y9JdQE1o/XIY+exHZuNRo hz4NGxWUcq18gFw46khlcXjLh4cawJDrRgavATCZc5NJopfrpFvA3zfogRPkyQFBfkubFdXXr3Uk bCNsz51iSP+Wu2fS8YZ+vOIcBoe39cH7Q1ckLo6hHl6w80+iy8eXjiFc4u3cwiHKJbhsHVYF2hje EuPInK7l4EFD/A8LqHnvV+nOl9pmYfYJ05fw7xAAobvRIZlbktk06rMMm/eV7H4nJCqKIQupYY9U 4axVhrgcR6ItTucDGxSUydJoNZ1j/MKFmomVCPfuFLQX6ZkVErIjlk77tzKMUPD2v8sk5XiDy1m8 ktRtkA1XG1nJC1Jb5o9ToP5+RyBhgD9m8pHGzQ4ay7NgQpKxd0pJTus8U4LIGmGt6wlFOEIqGmBB MkyTwKa/cjum0FVIB8OQDKW7mKEbaew5O32pCPtw+pcDSUG5j1OKPAvMxPtDMoRp1xJyMSUmGbvN 3fVTxoYBs93qEdXrPWYQmc8Wq1Tcvv7GyWyoJ8NCMV3ZcKhA1wPTardti+3gckFK0IBn6tQTSVhP zM8PrgVVmAjv9e9qSIim5+gyZOmO9fzqtXmalLx4Zcr7ecOR7KWVxxITFKrw77yyTidJb72zxHy/ J92TsZmoIBz8t+/jnlqnL/4A613OjqRzp4agW3H6p8diTv+Ug47yfPnf942X03b/TFtYp/K8qwxf 8A5HuHq+P9/HFJC/GwDKm/eyRDG69FgNKwuahAlmzv82KHmqQV4FdsO8UdJOEDCdeSiOTUjXi0Gn Wsv9pE1YaWnIBdIKTnlQPL+L2Eqf0EhZECU0GS8xkTtTuDYVCG9v52Z8JlEuuCS0Dg2mWNT4VU2z GJFccSmmxGKliK52LFKTRebJ8BhEOIlJaS6CJxjwbn1IjInOMDVAlFRIEK/ZQxIUm8iUEfhgExRK 7XPojK7mxYhsqy10kIX2QMLDzrSoimpJNAyNIYQtgZwmzGQt35qb5Ry//Er6z8pIPyaBPADgyEXF SPQ5O3RFSLpj26ZE+J4cORuoc1eI3TEGwrCBKqNwE8rimHRTAjtrQZY9gIe5JcqHp7l1i6V7zXdT +ZyUe9l1n92jQ6P6IyP6o3uuWW73RLTWkAYftaSKT3HBnYZ5DxlO0eVz2pfxftAPD+47gnxjGIpV cz3KK+J50C8XmBo13ZjLntEN4bRnBdCnZwDxC40GtzchXuiJ0Tt5csMUl9775oE+206zfmIea0Ct y0mbKVTNEGgBBAtXh30v3H95Qd+p3vDU4lfGPwueSQVNHjuspB87Od59X9NvydnGhi3n8QYjzSuf JMT8p5T7pj2Vuhf97oz22nRnrdeH0DDSUW/dcy67RiNHYbXbsy/pws5iykadDLQSmjlqewUIR2AG cxw9QqxkMsPGe2zyEgPla6x1jegy93JIJmG/GOzXIP7Sy+hiV7rdiKrh7Qj46473R8voUruZfSz3 sVjvYHXideaG0RkmZ0QjVFqMsdwJD2cdOWSvCyE/dRQg45u/48ND4zITsbNukVszMGRZFDlU4Pje abNjvtN0lQN61dhQ/sQ3LZX8RIkTh8SFRvCPjku0LuOOa6mxktBYYeP1EuLGKodYWSSbx3HCUTvQ eIbEaL7oOL2TTK50YlJjE4PJwWTO0fWOWvdp5xp7KtIxJyeGVHC3LBkPZ+9+ArM/Va/MZNAAQDE3 eXK0+tO+waHdqcb1mf75lsbFUuAdm6D+tLs032PfnQlBnQrFqPGbu7PTzHwrLz4BNEfTtNXo39+f yXhfHtpiSvJ5W8dI9uDPEdLdbg2Y3bDBXjHggWZ/AhXG+TARYlLlO/MXoUmGf82afDLPGZMePd9v mJujMnf2C420dBYdTXYtjPCKL/h96/0KhKTeuqVE6x55IDxj15mp6+ptuW/Xum3LDyA9k+SS7FyU Z5JEcPYKv5TYzmfPOj1SAIQMk0oI0D8AAJLy6ClJt/ruf0Mrz/1Im75P33nHAv1k8VLJy9eugFGj 283jXh3o0j5pNXPSZScZe7kOxCKNhej6e8foMFFpAJcWhkE3NwfQAci4E3xgDgDI/BvI2ROLMlPd RcM5gJJdhwlkmGpzlT8j0d9gYSopUNyBaKLCG4oXKn0gGntL+67LK53XITKe+nmvjp5jruvETeJ6 Rph5noPeXNDb/Ep0rUCjZEM6BpB2Ki1P3Av0/7edD/gMcHYPP61zoyiQjvUq6n4/SfZnBA68ieur uSJUJJGiNoBD0ixLYctA70+w/PlNC5rngz2R4pO/LDeuvXy51jimtqCuZO3yoJ/P3fipvvJwy70G 7WN9AFU2xAyGpvsyU7GSyAMAY3n58r9Hto/+LS+qlH+qqwVajqDb/mKe0tuH7n8i2Zs+kCnhKf+V hDG9cwgtcQeMvBgXbLwJPJWr844YfGDvlaiK3I/UxXkRw5neYZ7cD/HMPqOLp8+Pg1vE1j5yyT24 LilECMTsGLp0ifFOFTwmnjl8bfh5dMgg65HXIxb2iuxSGMux3GL9hR0y4GNJ0BjM8csmH5uLBFVs PO+wP9zB3WIYURT4xCZwwcrtyyjHof7jlo2bxsHWOim7l0TPj2kFiOAcicPEi8pLJ3UlImfUUd4O cu1QvbSiXCqpKBM72s2S0ZoU0fWodkkzasfgHdcQ57RQJ9aVb6ooF+88jk8j7eSoaquFyIWAnO3/ /dy778+ffeZqpPXByKOBRZu/f94z9/frzq4Trn3janMyf+/fX3OWjR4ni7WVd+sAII3J2cnFpUzs lNknHM6MMx7V/OLSPdQRtX15XfmoKLh84BLzyuUrEqb9bsq0WsphT5OyjKFQu8nTvlI2C5kMQD2J YeAnkwJ3U+asSOahOn5KV0XTFfSeI/UoHFqYq8hoMJp/XXCNQ6vfqrWc+I2PR/M8qnYdZJpnk0P5 r1j8CllwkooHbRdmeedVg+oAtl587iFG7I/qiHEvygH3ccZO3oLtSJqaOygjdkUeyHsfwPRLRIDM udUIvhDbRsb6mrFYPAuXbQXwUkvimsQ4p5z60tH9EdynxSxEFd4Gef15fj16p5/nZjm+CIkb02zy MiO0EGwQT/bwbQzW7KWG9o85eD1Ne0pDDCptZ/0wojAbL5us5bH0FfoFR9+a41bWHjdV8OxHUcM5 7WFZT3uIodYL4gN+lNCdPlxghdfOf/8rnhOI/8xoyDiwv7XV5IZgkxV/gRblJw/e/N/p/Va3qg+Y ctbqoXDlW/LnAyLMtp0ubEPV2jR4/osv5/5XMMcJnbQLgegJO/nV9gXyBEsZ0uRgucpO3HMZbXe9 iWUW3hW5xgECgROgJACovwpX2N4tNeM1fFaaot5mwmpYBcaZUGJTNHZH1kJgmzCuxDG07iJq7Y02 ZLrZ+4i7Td+ve1gYC3ctGGAOFyaHoNcXXDb10Ie3yLwm1b4JrkrXUr66DJgegWRAigMIZxR4lutq WZWgjvK5RxgLqllxeNzT/+ddaiRX19Q5Xj9KLrR3qpg+ozeejPPZ6tYQVsbjSSjvLe/5cT0v3CYH JumF6ta1HN4ctEMQmaiisaVVEU28HYC28+rE2JKhhzLpTttEso13cTJXXlMr5ySVMmwoUba7ZODC mqFNKi0TrRiPlgyNjx0hvOLRWqXlcvMZV4aGAhrGAw+hVATOMxTe1nHFQlZBRaaFX4TdDmFEZT46 PK883conyvmoNV05u+YDhUYALfz4vTwn3EJODDDPKAO8jISZOr45PdL2kIK2QFk+LqZQHA6S0839 y3ITQp7/wKrz0DznqP1bMujEMFoWTSjOaA57biYLULINB+9h6O2OZZke5Xn38EgkwL0ir9puwBGQ TN408TGdA+2V46YbO+zxzl7Qhv3cFrH478FGAtV+8cqTkKK9Gb+aDmU9doVyYOL/3c2Qx3u9nnVa go2ag6/1D74K6ruUaXqgJ93tntF2iQ4qvi5jepJjD89H5H5cjnYc41MbpIOO42aJIZ+FHyoN9Ef0 4UchDmruTnt2Sr9LovmrWcagU6IuEq/+cffmVxNMIATiJACYe3I5u3W256CxhW4FcDJlE7CF666L QuyWGcB0r3cVM++tQe3qBTCmjs/lIXCd7kFBe8BL9dxn6qUpC4FSopJF2qKg1CDZSdarUe0Kzkpt UOCIoFc2/Eu6/raEpxMe9iV+6wLexIfmnlFJMm6DzGDjojw9F0JrxAvPn5aBAAmqF4kzhzkliPUu iBHGCeoqyON+3xXC2nHXRQWJI6qEgtYS5jhPLKsWX8rru4XVhNP7qDqhy3u5obXqQ5yU9l8S7/BQ dOmtdVuvVvje8lQGeRd48NzX1VYIgTTXfbyuIlsjlFWLeczx1iKBlFVp1ksDQbBPg+Vnk7nQG45O JMwiYyIAVVh+qlcX+XX1+k0AZgeiQHqU1qh/Iy078KOHTZmEgn3cl45pT9JOBn7J3RPws6UmnVyO OVDZ6KTMCvTN+pMx+tWU0v6dYs8kmg5tsq7RbjbvWPcfE7EpQ2fGuem4YzMLZatiuZyApDoiuHTu JG+P3d4DPbr35LHciHz12O3hDZx++SOdALrNu+bmp3+D44u1RnFLkafXqilVUuOH6SL2rf9Mbl+D 217pvNSW8aiD4DpUXFErmAz3u7p+91nhCXpCPEc4cAJOvhUe0+lcqYhvSjg4G1burltbx8fXh8vK o/V0VvrN/kX1VlG5XXPFREX5xj7LAnGZq0+Cn78ML/Cc27+6KiVDnXDkwZH55VozlsqXzxw3IzcP TDToVm9ubFu+uvWy54nOlWpffHGpec2/SG95vpk0SApk7WFdWrSoL49PpF3r7c1x3pLtLzAFl7jx TQVDFBufHYaN/K+Cw9bGwWYW7Ny3QA+vslfbXOzBBcfNDQ7v9rLQHd/RXHNkLU33PGFr+2hwaAYm zHgN5KCh3qHDhoZg9q3+k6Vlk2UvI9Nl/Kx8ct5aXiGNSnftF9/eVxW+si685mwYO5EslZ4unE8l Y7Mqu9S+GpV2rNcgK/a/Nbeur5aOtmZg6hpkeFaus+NPC6qnGf1/pOSsWnmuu+9YmJHLf5YAorzY upgybRJ+/9sOjbVfk0cqVYiydt1fO5Qaz9YMhGpNZVzi8QwzY01pSML8XrkWSj2UdQzKIbGQ/XC9 1c+Lrucit2zEPaZ02A7v/HBX53HUeindS2SsK4VZ/K3+Y03M7TyyeVD4mVLHcwZMwiYz9ot8l9N1 7xaG/zpvld2aKI+ksDFGGpmGRg+AZylHdxcAT5pyN743LTO/knIcKgxAZoWRWPQau9mPOYclYDW6 /CW1BsBm1CSD7moR46JdhU5f2ZwFZAWLTi+MC8YFKiSZDHg5WS0I2JFBlSEtzKwLI0OduTQLcdkt cbs/GonpBDJ4RBl8DZj9gecU7gRC2iet4FoxyiWDfc+N8tNEg5ak1iRnnOvtEzUvSwRYy1nYW5MV /zrGzEatUTupRj/bMKVPNmUFWJMOprwTeL3vdh4btPwupuOcTG7XsFuMbtTNty7fAAvxodX1HCFv 7sqYMO+ZqXs3y+JsM3f3mA09K5ZPct12KT5x5+h6Sshc4DDx98gq/CPb0BBW/QcGCAObcZ9sDA0u w/HQ0MplfzK7ZIC2JJhfR3HxF+bhK8/ijQwUEMM3MnuiO61R7a0YubzITk9qolnT8E14Pc06xtvp Gv0SzdTAkHqees3ATJ9++dAb2jfaO5SF4YVlkN85vpsTVBLRv91nfRoGQ/5qU1MSnTKQXzu+X/4j st1rv7fvPMuzpe7j4Gxch7/r6zwQCN9rBfApcXwwvPGv3/I9fkPEfa1pKvM9kUX4XX9iHSQy7nM/ 329y5vClPY+9Lut9vzBf2DnAfSh6n8/t5/1MzFtvlacU0tvcmhXXP+oPHtAVDAKaWg2iFDEPVQcz XdqK0s+4TWClFVVt2Vxhe4pg1WR0JNJDfZJpjD/mHV21dguwnbu3LKpatoN5tSKVMQkg672j9ul0 JhqXcty/s8R5xGrQ0fBNgPYutWMe9Iaa2a5zG772/REECSCL5PgO/tIDhx1uo4g43Jk6QL82ujMp LzHo/iICVBzpVKrs9GwykqBHjq9n2UOMjpL7KEgowhRSi1I5TT97FpnY4suJcbSrf41ORkbCsmHm ACLAmiPxZfWaq1Y4jjAQYhWfFl7EkDuX3K40rJrHd8Zb20NmWY69XJfPmh4Z075It3Q3hfOhckHK G1s94FMYVBifdZDuhIJz4Sm0fnaFvdt2TEBI4GQ6Pe1gSuFk5B74Oo9eEJA3yRpiQ6AwRxIrx7Ng XFAQOVUnEafp9HyHQv+8jRH7zG093n3Hb87fKCjEFaqO2RxnTEcz9NvQvgXpM92BG2noBK1Uwq15 +0VaVpgWCDeqQldLnpaEJz/+EKXfNDEpA4tnc6TG7dHn+a4D/OBtGNBb3SY+FTYRhAgf84dreYn1 TrKeosfwkznVB2cJsMIQtNPC8zx/b6IQenvHOmDISWEkGpsnpBm9Ye26piMr3ZSCf7vmWb6GFUtx u9+i8KAKnl4bj4OrQtyO9RsTFInf27ttW0kEyjNqxMUT5YGfal0OpisbJ0QLiFiERlLBuHix7foG 8djT7Vh4yJq+wtqhGYsZy/o9X91S6+/w+2qf2ty6DjdgG/hRu/85/tLFdLXUJeP4a3tegPSOc2dy qJmyzp8wU+OvQ2wkdnMyorY0u69iKQUZXYi5Zuz0ICanFlF3Ojhl27aK9wt9p3yPTF79dmDfkeuT E67Nmjb6LOjj7pYXpoxOFpEoWQlHb97a5AXcK4kf1Agf+5sv6twhJngdWMtdzw2BLTZ7RLYz8Uc8 O35QcJOwqIP6m1vuohQl4ANx/mhCOE5gI9AT0f7IqQqUbfxeFNx1pnbNu1cz8FnYEQgUsdHg7Yst RcVHUkmHrHWrpypUgmjesM/CrnVGk6tI00i9CDmifv2q+d15Wb/Hq4/QQGGkQBFBEihJQWJLUAlK OBIxvcyfWrO1r6puZlVdf6b6ydPUZVSKQCKSE6K5qujABJYy6julhF7iT6nfuBIErQNJopiTmPmb kk8dlxjvANABfrMJh7Nkk4I+XfKmRirVI+6id0EgVwSo7wsgWYlSWQUT7dJXLyhdGgVCvq9zN49X hHy67PbiQRBO9aIxr9DcbHzBUT2weXHZTfTxeAWwHdS7c7vulA4BhKgqo+Q6V7PXwgfUW9gspIYn wD36tHzSwFZsKSP78oNR3eTwzdOaMrWQGR1gwysKiZ/cO7YbwysxwydmxJxXc1kVxyXsoKDXZutI 8x/RSaZiEostDjnAaXCohtWxSi3z7KXdNyYfmgyBxueC5RBlSADXLtdYQ2wBLAl9uKz3+dyBgOG3 P9slQMR4Fu06IvNK7ubByR2yqOH1960RcpkFEy81Tl1tSN2/DiUz3OZLjHHZJcXiFsfB3NnMa1eN aCWgBT7qvvXwelnU3pqUNyF3o+++FJmmKgTzUy60OGToZ9dE18gWh4yi7Z9SCNxSX/rezCsRO03O v4obPcbz6UDBEWFjCEVk/5Scf9eCJoPUhjeW5fAGWWQy35A7q7omh0ZNurCrE6TOnnmFZbjsMGff e7oog2+yLHJ4w31LhLwWhCiuIVRX0MvLtpKfPyWviAcQMkxJd9+KB6r/VsjcrUgqpIBpeZ4jUTxh YorQS7rWqynIJdolVlFRrgiP0RyFhapInbASbp6tL02J4+OsZw8rVRQhZg2WZmMSiI0rFDmOq1kb uxmRbUJ0Nw/fJfpHv2aaR5I+lpiZGVTkSj1XOruHxlaJILBPcCj0rgWT8bKKBzo/4P6pNrLgoliI 9PBHhv/mKu2Ts3ZjTu7OtbBdiXFkiXtjb+f8GstLF8jb/1hqe/fVoWsyfd1/8qHKyXImyyZI6oov 9K5zLHYB83hbDrrDFQJ54Ts42yhjg6T3+P5ujSQkyzhb8dgjOTUj7LF9amZy2txZH57GK5nv7KLS i3FXQeF6pUhK1FG1IEL6NHb+7AlcEzaqsE0Z5wHHzgtSRMeIomPICTHkGCC8j2z2pWx9pN7dP3Uk shb5TpUZrOuMP0dcQ75zmQ5RLC6OJkn4URH0GjEpNyLfI1nVk79aHPU+QG9piE324X0N+Fuj5oNt 7DgKvWyFjGalymDQI+g20Zk7+Ho9f+9pACFNp5VTL7OCoOm/ELFwSFq/qCbt3rJltxMqN1ouA1b/ KjNDJV9FWN3v2m/V6N4jP9LR7AQPczziIDRjmmaRRAfgTuFKaxIawpVAAksVPxVY+5RzzYJhIWv+ hwA50W1MzSBIucU1dpFMqfqDYwVBTPn6rPzGp/rPSsOXmtOhFdgIOujo7RfxfuVae3gvAUr8U3Xs qgJeTuMo2iBwF3au0A7wUhmGE/wDqSI/34EN9A8bXGkS6Od8xdgFg/gFvvsghZBXz46bkH07JfYl m218yt9uPLYKORqM5nI8MF/vTochWv5bwH5gdom1/YSxYNW5CZe2669KJiva78yLjjhwpmDQi7HR eeWqz6YKZDeuHH6bvoCSyX80lfB1yhjMevAeweLUqfnPPKq7VRNPTU53gpsrbizvXBnk52CrhU2+ QqIobxb7syWL7GodLCafvb0oFPh40vwTENdO/sXqpnXyarKonfRV6/qcWbZpSqO1Lcc5NxBlAeS3 pJBUPeo7lrmXHxhs5pC2NnuQNrRRurvr/uHf8CqwgmJ20mKad8bAHlT8ifnPH4j5LEwvLXQeKbTe jrQy6qa5fWiO+w1Zq28LwxgS5JX3Wl7vEpLdMQ20EP8Kq21Tp/cy3DBTFb9xewGFYn6CsUA/bWgP KF1cjBjK42F66VNrsJ5FWlMVJ3Bx4DWvB9htr0L9s/ephxumAYjeV/q5imjh+NWxASQDneBUBKfn 9OITdE9MEcPT6XOfRaqwyZVaTalctDWmRllV61fCDX9CJwCq8n57ntRiOIayMiYInidzulla4KDT Gxau8+0tCgpGLBQ9FWJfS2MABBJka0HKJi1oSvauVHmzy9OyIFX+Emdv6aUVjY4UUoCYHxONTUmJ Fz/VuFuzwnExMrYGzTU2zjU1JpnI3P2I2HcQLkl239dhEluvfTrcnj0dfA17RYyE/d5RGLhlrXXh Ukr3KVSAkYdMZ4jw6HFv2frw61c6HUfCLcfGhxa3SclkivgWHxqPXfacOF35b+AwGjMcn9yN6V7K GI1LGXX+9cM22jarYbTDuBvbwv2oCdJaU37DCg1265iN9IY1qpTkoIgNUZMVOXDqd0x7h7AgJBtI dNcQclnT+wcu/IVlxn6aiae1WAxe/sCXNJhuFJiww0FuK8pT8XEmNxb2d+QSs83bt8dSp6r0+RNA yGfI5AMnZ4rXRMxx0yXpKl+h56CJ3LgF2mA8z+L/WWGp1XZYQQ1z6iH1ILcIiiHARAEhvJWCfdGW XC8L7i7XPCARL5wP2ziGIXLSjAEOaAFB8Nq+CHCeNpfn5jm+mQQWQZhu+yM9Wm6j5YnKnZdKGtGw a8cwjmxQeIqayy1gDvQPDo6NrVp1Sjhfl59/8ODgNcyHnF216ooZHFzcE1nA5RYyNvzr1wOLI4GI fhPZgup9uIkssblq39p/yGRN1SnJ6HxNTmmqWtIbj6FwQpJkMfTEqa3xHixKCpYXC1wiYVAlmI0K H7U0ji+CIZ5olIB0ipGVGnfGz/ScUe3Av1kyl4Jd1LJKnIYlFMpFsBLAFKV6GiBRpdFhCUINq9Ic LNXul2L+zaodae/P8/iHs1ednkv/TRninEMJBcNAFDx45+BOFpTR8/O/H86b6Ky7d+6Hnd30fcde n/U31IMHfa0FWAAfelcLPAOPaZL+T/e/JrEIciVzl+yDuHk/Meyq2bL6Kc+6imerJHh4zMtNAggH LOlmVocDmS6nIsy0nYRBVe62u+bCgQcbySGCaTnc6hOo2veSPAhTvWdLKDxz9YCzskZesaMnMG1j XauHd/y6s7wzr6P5CusqSOaNm4/vAdxTGneEUVv2yf5c/TBHTYQaXnZIydeocKTvh4OAUCWJLsk2 l72FmjAP4bAHjnuIkkms/04yLzpbwGDC8XDjw9Jce0d1QNdLo7UUGCxKUwcNcGh2aG0SPAcYcckg 0Wo4SPAu5kUDtYxZudT9w6H2teW8Tlsq3xHY7JntOQ4lDA4SLYebmqoGDQoqMYwmDg7+j0Vt2Dmq W3FOQFwbUIRQvAcPwC4yFJQUM4B+TLH4NC75l0LdH+JeR+zWUyTbp+NqK17///Q6HiupUmd3TPDr OQdsCRlhyN9lgIxv65EySk30wmMbJ7FfeESyKVfj9B+lntvJeUIoNX/cpvJpa4ZkUXfzSnNyM4hr jJjbjDj24Qluozvzgw0hbx5KSnx7IJD4OCCnQmUkNTBA8amLFtYtxwLPMRWcZvrXPL+y1YBzvwYb bZafMnZiwfwn8UkiKoaaiT8fcDzYcc7Y9yHs+XXZ7KI3Sqv3nL6TglE2jO/TCG7LaaOFeprTbMQM ih9CQ/Gnl40CDStwPdPiVYLok5aHYpaqXX22yCxNnBKwCSsP4pPozIpqtsuK/7fDddyWddm4GAzh VAxx3XgVkE5uO/tPmb3bSb7CG5tC7ffzKG0A1ldB0vN66aY7KGggxBskfXhsRCeX/8HfjVNNe2P9 RkxhJ0oTiVC2CCk9H8DGeCs7NhqFTO8ix8NgcH1eVJOJCYmLtscokIb5u9nVsAJcUJ3x4l3KQCOX 2+a/rM/xYWfNLjgGGoVBVokjjcW4DJQdwpXncJ3hGxNqrYPBYRAy1/UBvDDelbcMVhJu54w0bUOW WXKiAVwFtOgsFWtn0q63ms+JdCuEmaQzEX1BMDzJtHQByy7QzbLO3L7J+WyOUVGx92q62/GW28aq lMgIlpVndyfvfGuYnU2mS7B9C1Ilxt7RXOR2HaG6V1u7TdHtd47sowYLJCyfpCjM2RJipGWwQ4iR K9/hJMM3INSmhGocH01DCbnd0NuZqRB8tkuwrcYgWWLh+EwzGhgVYOTIyWO6iwSkCKGFe1rtRcHA 7z+DI3v6Cpt1gTOiwNWleQ4T1mgzC3RDxQdH/vQO/PYW1pQEjYqCu3MzDIwWPaqrSqR+OzKwS/5N PuqH2P6iB/IhIe6oVymwGiMj5ZIpBdfK/LPTRCqhinduJzNJLqRSXgt60y/Ksfg1FNd643bXoEMC z6gngRWBaNRRKr5w6KQv4TtFIFT5h8WDInw8TRgoD9L58bJyhnJzeAGiMq6NjL8xhjwYbXjXBbFL wwOYKMfws0ty8/slgegtjmInP4md8V0ov64/71ITr4vS+ddEz7cGirW9fJtgu9sumUHUDjO2+TeX wKBIvQ6IZMeoQREBk5XRyUGFsjpuAjNhOqzPuc8pVphW/OCwu4dforfMH+vrGiD1lFjbfzE1HhKX LJKtC70m7WwU00k3XO3VPd3e1dblo7PWFAKQMyMPCw6vtUbtgh2uzHQ0GCQsECVLkwEbHRIrSbpe yPnP5S7ugeuow4jziFO6IvSlsyA4BsASbC1eGbnynjC43CvUNbvHHBtt5FD415AIMeh2WfnUzelQ 7YGg3gM2hb+ZVeid1CqHSiu17++MTepG4b7OCC741YS71L3OudRY9EuXm9Rc1ds4enqtsiDmdhyF /D5rW7apvlg/hhD9mrbN49Yfh6rYLqRrBNXWo5LDTKfajNhvIM/QOtWjgJsj1QCK9T6QZ8tKA22W grBRfK/Lfdx9l7XxVmO7DafA/ehV5DXHNHOcEE5haHsv32i/Vtca7uGNyw8wqvuAyS0Dm2KazJys umSbee1uvlxBi2s11wk1HGzUL7dOrLl0sX1Za1dAS0dni5Rs0jv75AhIq/KZ4bqmTqcWLIOTly8c A2+qLLDerqEu3rbeLqADotbquM1nfB7DgkgdnpexzcvDy5VCnnqUoc9dIImfJNmCQ0Y1yECyLbJY 7wARIYFFp6qJTwVwTGGw7PUqTk4hl8zwjnE5TCKb4THepFNk82pEECo3dzxwdQiSjyhiUF6pTRss rNgUg/lt+FfaFBnuGRPkRxWO9iDorjTkHeB6GAaRwuUJP9wMwWL8UQzZGARRjVSQbAtL7WiDvsDs H2KSIKLG7MneNf+yt9d4M3AeDo5Ll12iD0aVGKWKCJmy39ypMrpj7B9YBi+GykaWKtylQXd/sGJA Gc2h+AXeHe8qoT0llPn6qcO++fFwtiWaTgMZWX4bn+f1a+SudC72beUPSyvRuXZa7xMM9uPyoabb S0QbXRAh4iVLceGj2nPlviC7ub1jkLbWDSvjx4I3TtIe9r5YP1K4Qyil/9yTNSVtFYZ3WXm5MzZZ i9iB4VnBf7tqJ+Ziw8yTdsZmvztbdvr+BgZAfroNX7a6BD0CrDFfWmEcPTRVI1PlszR0YNwOB4Lq kMd1krSVBWzJAGoZ7SOZvnG69cs/ZndlR3qdqBpD58nJjnGF4fvaox42RZrYbDJx25Ta+auNxoe6 NIdx7XkO7AOHdwVg77xSLOIEVQTUUqKvEu2vX7SxuciR6mcxJIJItm0xHlGNLydZ1q32nO65vX1D e08tUvWGBrD02pFVyKW4k9Z31JKxJ34XFdRlUOo8MvNjt6SWPX6GZqon2iPPixGlfrP1mb3hPAiS rZfybEJOoK5QZkzNHd22vMng8UhLTCdLZTuD6EJUImpVmJpMtqNvN3tuaYwP1SO0KtgrNcGrNRbv v8YXE4s39NYaGixMlmZK/03uaEvcUZNmZkDOFGDhkEFS4tIjTXbFjYE52pQUBulymTSe9KIjo9Ro tXh8tubxbFoS4eCklHLy2LggLYKcHwBWSxqLEqQMqGyvV6fUNR+Y1xpSZU20LcQcQ15Aa6HUHmCp aUOL23VH0iqmoi9XZtDDqqdw/tM0qiyNG5NrrsGCVgwNEmJtRcYp+35Z69Px77nopEOqqEnUfUVx saPnlnv74slapdocJy4LoiyaM7HBIaMp+qfwlCbQdjCtL/okb6frwEXQM4CuABg+yFcaVQnouwXX wMOsE5Y+Psn9ywG/FsAQ6xCuHwI0cJCF6V7XRUtnVAqwvMXMIz8fU7P85hYw9NTROcTyKkxh7vQU AHCRggeVwGd3UdRz1Spa3Ru9ejUxduyYmuMEXr9eW72MpFRZMjPiF2TIvtE7brFcVcqXoVuTq921 XKEjPzlM5NLMTLDv2MwSu2ljlDW+Us2ukty96sk7HzbsyH72/xRslq19ehJoHYL0f1veCYZyFRd7 lpxJyFX2e+d5KlKjs906LCtcBwdTLnSEVajFAakfw0wVVKUN1y1Sa+hthyzZNl0EC4JGUv+BHIx/ KDGkDRyAZPiHMeVA8oYXW1/LLWMru6AeDCgXy3WyhniZp/nkjlmqSARxXYXYhIVL0SizXS4sMN7G MDII9yZneveXRI3wclXVCWw9XpZ5sDT/MDQdAstPPLirpPhoWnHMjHuRpaiUnaxbu6sif3omp0xX EFw9D5cR55fiEkGv5GMCCod6sl/kHUikXeOlMQxxOyKOy3xta3Vyj4UEQGurFl9zbd3BEws4mLRo F8D/fn0FYAcnRiEjg3+0MX44pnbhX5kbp6rCiZbvGVj14SAhcVHZsLt+Nq1Jm4caCRWfxeM8LmyF vehPekvxdFnOxORW5iXuv8qqXjuB1ISdzHgwVX2H7nGOOv33/rYDpNVlORFde4titTDodkXqHztv LeDhbr44PjD3AKBvbiiDMcf/xrlY+GpZQQ5rjIJYK1CY7ubjlv6iTSxGw/sGBvLsmgRDo9tVwJbQ JZQ5lmSd0xdOVGHICgAhx8k5R80FqSue+xC9TnBtdaFJVDRadouL9LS33WtlTJ/3zNYdNru3We8l aHzybP6ctWt39ueKNk+kVxs+MWqm1f7XB/jW9T8GzNLuHKFB32dqX7jhu+bwn7sAeaC1lF2J2nxC 6eIT7UDvcRXxubS9S3h2hI60jVvp7ja7qzN4v9rbhcO/WnCz1rZ1caxzsTSW8KqFyCVTTnFFeW9I 8+9zG/i1esPTkY1DG6DWLBTfocyJqLM4utsUN610VhCVsDDYcbwJ7csTwoLS6dzPH0mdTHevCtNA MrTdQP9yqRna2jFUHSHdMB6GAyh1gZooy0k0bttDZiApqTQiN7Ih3cmZaxpfVxPnWshQRm6oJCeh 7ZQq1F5l2ywoVgzE1Z+z2N7ssExu0cYjV4I9vdMxibI16bCNR/4WjpaW+o+4PEADI4mI65gNG3Y3 rtr/8tzpI2+6B9ZvRY9dDPFgiqPjayvwZr50WoSv6mbnFcyG9Qw3vSSNY4pUKn3DIvgFB6+bXrik fLuDIPfKLk2Mpy+yjLnIPD91YxznJSWzOHJuBcsuKxqkN1mp7zPPoWEXj1EMoDfjBev5lO/mJp/K JiZKKIQDJhQx19qeNjc/1arLOhvsGW3XsPwoWUGW1VTWEQeSbw5VOM7SLtEWaBUQtjFmX///L0km I3Wo9u9Xtdpi/1IpkWj0K9osPcO34RXVPgLhFmiZ44BkQ0faCyrWkagykqlmWUf59dkfeC09KR5I 03q8uq1TI+YC0Q6neUM86/7cSBQDzMO3Q+QC1/y1i5Ubt1eCwgIDtIGyUXwlXWBGXiReDOWbGkFo 9C89MAlsMYxhhHA0dZ8MFveRzQSX0yWcuP1u8fkYCAzCNb2R52pKwztgUCu/OX1bhKKTZex+JVPz GY0pPEj37PMcFndEZfZjtmrdA2JkJjADQ/LVbKg8HLFwJuHgqbNfZk42HzlreYG2bGP1bYuRRErH J5jaa/+a8UWfKov/A0mzgQpdNGBjolKrRKQ7hJo+ClUCjm6ZfDB9ZP2EMwnS5yd+/qY5zD3n0VFB 9OO3jx9Fml7yO/pTmHMZGl8wM70U6BcTEe8b3o5t6zZ5+WA8yqvz/Z+2Ui8gcS0CertKpjtwzZEl gfx4soluLq5avYlBnzIOfdbwhM+8kkOHQ4Sb+IZ0gYQGJG06dLTpRUomYLStee+RJnTNfqQ5CPDa vmujkEIVvtBOmfdCUBEMxGTmxdY+fFLtZZcUc+OSOuXKNWl6dxrISm4vi4kvaU5jxyUXt5Ci7e+c qkhH2GVV+KZissxrjp2q5OZhPD6RJx12yVbI1qGLLvn5Xy4krw1pA3cD1QtrzXb/amqKuhB//Mmw yD45vtdroxoRBN5MM/T1cK7L+Q2K+BbfctVlvczk5P87hOdmV3c3dva0omGMNqDWeg8n5cLmfJ22 Lx6w8q5bsOElQyOPJsbkJuZb68JvOFRNrcmcLbgIB45P1j6kPCKnk3XS5Izt7GQmF1Ki29xul+vy uy5XQIFWsbqt696+3fpAm+q8prM5DoP88vHJ0jwhLeiQ5W9HBv/2Df0dpN1rZc/e27vovCgEiFb7 lvC/JMmL8hUyA7BxwCKA5HfR/l1cFFvqLHTcYXCzXn2Pc4RL769m+/ThVd4tadhgM/Et5Qhrklwg plrjujWJ2hAx8rcprwouykvHtYdG1CACejOMhkSRty6dKXOKg/5UFpLgpZsVUuNV4Vr27W0c19vX 0Lh3xvfyGrna/XT4RJp9WFnqEOyDwlLFzK8IdA8pCTEOBgXV9p0V9jgO5RXsATu+9d711WGWzFwf SzD2c/vSihWzy/tNy2elS2PGTVYsLynfeDhTuAswmmTz0bZCBwR/sBn477H532bll5U6vf3KgeST H2nKGZg6NbT87rWNUWMRdQnlNZr2vDZ9g6lJXRshGzm9d3j51QNjGff8I2Pp/+0zxaqwtN0ZSvN8 bcdSeevd1ssMmyvV09HLe3rWNa9v6VwTnZLXXp+rMuhVbnlcJOoD2RYhJE/cujrhVsC9TDbFqXCk Tjfadk7GyR9/TnjH9gFBK5zsBt1lOZLR0SkxtFPsJfltt9w1CRy/NVLBeuMC35bzPIJ1OJdOuv7j bY452nq/GnFDvRZ42nvFcYg1TFxaCv43mRm5vVx0TeCo6TCccgN+tF17WYtkaaW36SVL6YQl3aaL WmKJNsVdj4zN1C9PmX72gIMqNzt96K9Mp7RzdDODGVBeb5c5k0tOlqqoqDlhoJGtBboA7cAIsjQd XyfTEifAOGHLFlOuZh53J1wDDToAWJ11afnAw2zK1dvDl6Rq11nzoeAMnVY1GiJsBTafVOn1FD2Q oqi0yw4k5Npolto20yQzXies6LVIO6Sj7Vaq3ST/iO+ZdShSOoZ7hzN4DmWJOtfLuc+1SidZrDvp e8B3koTeSnTEeKY3Jac+zrTUpMu2OFTNTf71lkpmSTrOj4q+aWmlWhz9zca00DMWHregb67VazVl GR31h+8J41BGwq2w2dmkBf4TuEWgf+qbRZbyREvbwYA843HDd09tJlBFweeDfVgFKlHx80ZjljHA vLHcJJCPaawtPgi+BQd3YLIcjp0GumvMI5qmBUWk036YuTNzystxzrnlquXYXzbb6tXP6KNfvFNx AnGlOxy1xM0z3t26j/ze5uaXKPmYtNq41WUAWSCtzbji8c0UCSCkakoYNVhHquGwUANHXblv+4dT MJ2Vn2AB/1JxLcwTpDsK+gJlmv9vDXtf1arCjPW/9XM9MeBjUcXROVKDHWEhJcHrKoU3yDRdLRDx qplcCJuJJRjpvTTck4eab76oX8rRAQxvx+MjEU5oeydZ7wvnUqLPbG/WuvKShyXmHmc36Lae3Brh H4RhlF9fn7VukNcaF0dNVjReA599Ot+G9VmEr8Z92WUgWIwYtnQ+nx1sxm4k+g9upYDAltNNY1rF GuZJ9oNF1i9oGr9cUUaFp+LysvpuNqLKtBzUhbAR4dmpAd851Mzs7Gh7gWhtleuy1k+QB3w3q+Ln UgKQTIrOOv9YyzsAfeWuccgAXKbFWW7INtCkRKIYXg7769j6/7+mDRcnxIwsekULHhWzFA24RK3C 3JfHMP//sYKcyR8Yj/xuIybnZRLnm5YTc4q6B4b+Dpl35FSUlK7wC4usuSW3QJ7uz4vL6txQP4Q2 4/GOKt390WKdjvB162rcZt1RsIEx+Ku8oCvEq+QdZQ4TdjjwIm456RuLgDTcSbPyrKixNU9mx9Zt IFW3Bx7/Sw9vx1YG+3SXNVyq3SuB5q3rZp+MrYE64xdYJV86fkb8B4re9CAGtpd+0yTtruJopdHV rL5NIY/0qvVbO14/HmnFVmDuyWOX8wqy4HNi/Mwy9pj2lnnOnWuuJk3RHvyeMXqKAjMbHv7djA5y u4WJv8Al1jzobYuX6QH7rfsewJ8RaDcbid8/4az9+rDdjMdmR+oqhT3Wm7DbOvzf+xs90FO0o2js AZMn9IcH1bsvbpwxezh9Fer6kiX0vIqcwUlEebjqAGG49gAPoeEB9U/y9M3erg5G18N2xmhXd1DC /jUpFM7O0kXXvZiePtRSfrD5e9FTbKX4D24ktmNnezufG3ZsNbHmiRbH1yakjnbacF73+XM4Ii6o cOGuaot/Am5AdFVvL+R5D72kwVzKgFG3fz9vJ3sxm43u+/Aerafs6rW03Y5t7p193tNiOIIi6LZ+ wQ0203C8+f2BmEuBMwNhpEh1xytzTseYMfsRlkLCL+JeHyfakDRbiSXniICUxw3mSE/AaLG+I528 a1XN+J56wGwB70Tbws3Z58SaFTbNG/8fV3sfDtteZZgN1DA6KBeWmA9tYmbF+0scOPI7HdhRVprV i7i4YncwR6YZFMfRQ+NpMf/ES5PDwch0h3i5vYZRic6x23Vvcu4cCnrWxlFytdPAhJlMhT4RJoQF FFCKkmpnhwizLYaDMjcz/FFMDI1u98y06e8NKGUXAAofGu9Dq3IxLtMjvZtXHtapR1GpzfV8zThK SmVy6CFDXPGE/k36+pn0N/8AhDT9U+RpL1atSXjzWbBBA7XIEqFrzp+voYYbGFjW4TMbkyY72gby 994eHjECnGMQPXeWzKlxoWdGOxa1R0ZatrVPklB7lkCBOQCQvuhevK2lqCs6idKyzUifMDR+pDto bi8itMyCb4dP8FjjsQ/AFni79kjVE8rwKXxYOcD++1eXNaa9ra0dg23/9Qt5h7/5deCAKoLECJfS HKbqGKvhQQRv53KOK8/cOGzcJG5itZUZGblTqqQJg7iGj8tDaViUJywpiyTnJm/p7k4S4rhoenJ9 3wVh33F9Mv1gqUwy+nuYkK5WtQElZ6X/ZJLlafvMFrfxlyd36b++9u+r1419f9w7eq3A6bdqdFvs M0+XmzBXwLObAhwBMsqGB8WXDqThOQIado38oA9hONEjMmG1UysN+de1N9wrRpVksp31o3/LtdI8 s+w0ezOfnSw3pxP2Rft/NRt+DsOSqNasljq6Ncocu8fEyiEjqb1y019JVUh42KNNRHepbY3C5Juz pTLQvjTSp0sNpYTXYJk0SnkhWuZ45VXJtzpkRcG3ypDE2CXOpahfucGJNiMKiKVwxsTZU8IjHvWx 4xVrReJBj+BXE0/uZhV8DapTzJZwGo0q+OKCUG+vemEewSS+RM+UfFGGJG9zJDtqo0MhUdCDI0Da hyqsj+u6u6Wga/uRkw9dL+Qf8lpDiueiUv2UjM0dne+D2AhU8n6q1fQUzm6guefNc40SioRNlbBP fCUXV9nU+xFLlwRBLFmRxYpdkP+dy2uQH87nSgbUXZbOKzxMHu4MbyKapkaQuyPNRBBFYaSbq5X1 kIZDQDbloEq/nCzB7jX0gVRPoyYHdDDx591W8n1Ke0QC63Fb9QElkzNo4qDnRVrDXci/b2LTu2XD cN3xs9n4/duZXWHurtkSTP3h8N+Dqvwd288r0DOXhXaROXYf/QxMr1lWGNZRpDglsyMDG+aaHebe xbSFcQ4z6vk9V5SY87R2S4D5hV1ENkymOyKzqnMrMY87DQmOpRc0xg3wq/ArOR7n9XTWrahSVuur tWvmVQkyZllFJelBLiQHAjFEViy5qgNvW2G+cAXmQDk0BhZDhNyAQsWICETYGrcOSPbZP36V7a8p HqFm/YEMyPEGnqBpJfXcWqdZe9SpkaVorgDSZ0KOnKUn13i/8nYu6kEpW3L2lX8pw8Jz9Zvs9937 sheKh0N24mtNk14eOTzfsmnwJERcF/wEbI4oqwp6a4nKPKZXS4jEQ+5ueb/I+XTJKY9M8eY2jVqm hVIgjxv3Hhy1gkDCoQqzxEskVA75R98uez5HRKkoA1H/XSVf1076leQPQh0dqDfZAHRW4OvZ0dtN j0lGXw9fPrIz6ZybqoupLKghjsczqhFMfPBAFNlD0iACVGFgfdyMut+g7lqpsRgVAJndAbkOvXlJ K3hd4af5V6g+Vi7wO13XDdZQ1axrfH+2j7gwp6FQAM6vz0g+nVyelqHKZYq9RYcSwsdMf+AmoOsh 5rj7zGPiFlGFHz2GHmEs7GONTLgykYo3/f/xptFSAUKGKWl2vJCN0bZ8R3NzxkC3rW6oPdu9X7Li nGlY0ShbH6ZqZg0gtVMVVzNUmx31qKfjrat1yBynVnA8Sph8LtLQQr9OqwwdE7DVrKJacq1tSzv/ 1AwaTzj++Amr+EWgBkzswSPF02uj7prwoqONYgKGIPhz7yeUSQf6bmsCZ9WlKqBzSs/nGakPt/7V /1zTUP/QjMu+vXPbC5GHtmzGiSk03BE0sJIxxoWF8TEuWAplLsye1+5M1uLCQoBZPHbjdGuobY0Y IQOyqJixlWDFysa8Q/mYQd0ugF/yCerVuFDx9lS0KZwa0rruKzVhbLKST4NF6x0xvEZCEdShrOUQ QJs7i3BNPJq6rmxexZNPVkjKWLKBn356reupp7pKbwhiXoEJDPwuHLQppl0uC598MgYRqIb217pv iJIXGaXmw93DhqUZlttEN9PZll0NXbBxSLpf2dLv1Uhi+Gp6UW1MWXCnja5HfZFdnkbIQebr1aQe BRBSOk1U9ldjvWPHAqO9/MyQQNU8BQX9JrgZkQGT9CxykquocFiblCaMlMipUBgecfbfO14yxxTm lH1CSFrJP5jr13b4jRlSNUeu3yEZO+Wa13oMZnSs6n7i6PrE+1VjCO0l3wQb7+8q+nZ4y5eUtuA5 3tQ2y6Obt3L9t2+zbfmWcXhb0TtKG3IyvWlRN+Ot43g9gravPm5SN06FkHA/EaBIy7QnAa2c1Ld0 jtDd+9AEjIpPGVWRrTlhNITl9R9uv1O8b9WprEZUclD7JK65YJwfbMwvTbeKOoRtVyCkFNfCu6v8 RvoezZEIhAAfISBQn33vLjFgwSIEkowOMd0zluswKxFxOlNi1B74ipOBJv0LKvYyv7QD7QELyqER uPioBWoeadtNSc4soP3xYzcwerZR+bFkoncB3+0VgJBQd2djqJ5riTsUwMD6vzh27z2XZfmqAS+N jitXi7dLVNBzTEHJlWHNgLFKNx5hy0mV+jhpzOSuSlyIf2yS7Pjs5iPzXSJW5G/jGmMmp2t43716 N+aB8JaAenjiWQA73Z5Cs6/Idemu/7c46y7Z4Ui+edLL1hZO/sP5+4ct//RpjcU2CcLA7JsGQ8+3 gV0vBgNRoJ42EgxrUZA1joit7Jyuvow/CecKdilDq3J9/hILKxMJvnx13lJ698p0CxkiubMlhXjH VwVEP9eV/WpnI6oYCUAAY5fCZbN1tMBB7XJ4OIdLTeWPiJy/+oUwZcMOCPcfby9jvTd3CHMKSC1i SVfuV7/agGGr4PkayVxskVO8fk6kjC7XxpmA3EcxOQfP94CeNexY7bVSQzJ6qJ7H9OEimkELLJ/j Oqc0ihmbQhbLP/RaE1mfVNgjR0kjU9F9Z0Z8NnEfOXks8DCYaMmwmVeIiLKMTNij7bDR9m/f0KJP IpSjauyRk3UToftnFXoR1vcLogZZnZWluk/M4U3uGekvRZnGp4B0mq00cgeJYbOeRT6xsx4f5hdC 9UyTM0NusG/4dEUyQkkBwew45krA/gGIK3TGe57BVK34Kb2p7Ia9rn0c04B9dSL7Zn/9tpyhFXpp sgQNlpC1yFiWviGt2fM2JlvWYEcAFvcDtsKCX1T00SoouME3OtiQwBFTy2DpyVGy+0ID6Qi/eRji vMeG+VeNz12xzCABobOPp9tb2w4WY3SPW67yQyl0OwsHGzafYgF/KnpJDyTy1ER67b/1TgGHzKL0 6QNNsPJ83SNr6xUza0J9bjWnrcW0cYKt7aRUe5/rLT1x+untLVct/tQdiqKH/1tnH1XqlT84nOtk zvg/pWBN/XJa//Sq7lQzTHRzRbKsJc9OnDUrTZ2wP18yZWshIjHRrK4t3a2g/KG3LeGnjB5bXnUG 4IfYlocBDEvOtyiI3ADijsNce/B73gmlDqq0B5YNoTV+2LjdNxBkpzhzgyPYOTU7xnkFkPT5I+vy H4YZpvsxXkjKfRRbXTMaViQ/mGdclFC6nN1Iu7Yt+eePrMllb/LcNtZg1+p07N7EgHhTXeyrbq/p Hcno1EgpSt5ZmLR+C2oa/FiOFlrriltTnLmo0l1NsdEaCnMe50iER/ZDv1WsdZHhIq+B4bBhTNyG 2L2CKgpZV365yWyYCfE+ybGUFlT4/wFfNOian93M3JJdlPO5r4xe5PCXXcDckdv4icqp5yhBDMcd kVJbTnjqSpKRr20ASazSzbO2p6GFTHlaHFXoFwarbyOuKgWk/tkKjBnGysaKiGnDmGFtLJHiVmAJ WDqGI5s1hN84btkzjGlF41G2AYe3ldnXklsPbbIRovDoNsxwBxb+9Pj7NC8it97XWzvCO+3yUK+V vAqDB9R9qLFzkMg6p00KNpdw/1JlySq93Si57HjBsozkQuo2Tj5PdzvSNHNZXlriEMczGXrDKchm 3qlTlTgbABNsKpF0HxwouPrKSzt4LFtzc6WNJNHuy5ZwwjvP3fd9SILUbKFAlcXzZhj/+H/H0ucG ovDkE8/lo2qJXfDIycmBvuNH0UE0vfeFeuii4VP9hM5zmMk0U8l/MuqBJ0/0atnEza9fn6Jis58c xOIi1m1ibBQeeL0euHIQi6VSlTEnT7wzaEmsJlrRrD93OvzU0dNCRPJTqiSe+r2MvD0M3zweFvJ9 fGosNDirF5ybEDeQLCornyx0SoocBwHRXWJROconz03OW7WpfHinX6xe9WLn1FiI5Jyn2/QrVV4Z jry/AIs9Vn+7ru7OHwDzrT8ZcwD1f0kI5Udh1e34pWPxtyvKFTcGhi4nhf7dbIWlJER1gKG1O+Oa G4vXHB0d1tNbuqzlZXFI1uuw2i2Jtd9WAd6UtIzrLR3WGz1YuKbVs3ln8Uj2eNmz2e5igHCiotrM 4NDhgYxVhw/lrpuvx59pBc93Ynpg0gWPM9WTOWWcC2SOr7nho+iHh99Hv1coL5w1t3g/9LL9YGju 63uJXK7WLlaf9LjU7/njs5nSk8ph00sp0alrwzmxZp9/xIHor//a09L6xQg363fe/GoopsG3tcJz auWrNc7DifW0QKmkD2O+cCEuylPeDtc7eqK0QsAXj3BcvBITIaFZ1/sgLY8cEVPWvHzZTTrzbzp5 cgrVZKJN+uJ5/IrtE8Y+f/6QO6cnS0gFg1B+odjhJkV4GEMVFoqlOboVGwIkCWEjTQBIymt8DukM QbgZ81KETVL2k+Xn5fEVOnmQEULfV5QZ6hz9dcThdolN9ru76+J87j49681YBREBwG6HIljIZuZ/ ZNEL73qNVNLxGRAkFymbBkPAzuFmqSdk+sDkM4jaePj3TZb9rh7RZRgE1Qnz7Ga/mMTyADm8CWNE Z4jbzNuHi7HhSYzOyqKOhp6W5BTvNGVeTXFbfW9rUko3+WL2Ro+9i+AYjOFKv9KHo40sG4UBFhEP wyl9rf3PbsmBzLP18EMmZtuW+WcEKHybyroPjVgro1tjfJXXCrYgjLbDMWhkoztZUPxkuIlpraBb IeLhWLmPpfTStgKNmahBhRTxRh+ZttQNWiPW2q/E+Ea+8lnge/emb7OPASHDlHQfGw6Mi1LkLfAJ cqvmZUvVh+c+E/qodaJB0ox2Y/FO3HDoGnaf/fCwycsTt7HJv843P0AVySKjV0Nl6bir//VJXzaj MANFylZzr4yKC4h/5+b6fyaBqFLgfNCm8Gd0I0HmzVgbkJdoTttaCp20FL8rLYckNl7Lb+OZm0fC Sp4ZihtZecmhddjDnQoMSsAXMVYI0kUcHvVkRxOEN5XYNuSesUHcaO7nMWc1YTqiLsjdHJCid0Gx 9Vy0RXY4hoXd2BPXVWIaaDECc4MsiFxeef/2LDULpC9y2Vx4ehlpMLOZl5b0D6zbqgFZXlr12A0u O3F/xNrC8JqNrje26bn3P33fodzb8qBT6hBsPcBXMuj6k8ORnU2a+OqOKtlY5PnUZ0/PZQ5HVYd3 1hSAKxrXyIAyGeNSqh365dRI+s60MNn6yI3PvoY1bzi0Ifx5+boPejqbCVTChvPZpD/2JXy19ULO Jzu5Lf2r3AdqnBKdQjMVlbztOQ07fc3L8jMTiwaZtSGXNqhKwlekb26PVqcpdGukdexDj2w7Uq/8 5N6Hr7p9ZHHPrSOgTLD51Nfa1fowDpt6W9JpqrPrVaNbar9+sUxv1532lkYmOgdXYZqheUbrCRnE JJFj+AdmisuOZA0CT1fiAaP+RtwbySAIv+/GlE3WdEYxqqJbMgPxhbVOfPm//kqP42abOJvIFwyE lKhE6bGLgYatQqzNjXTlbkDZZhFVUj4YO9bQavGHpMNeJcVlpXGDlnmoKPdIXz6AVcQZMxwaMnMz M/WkNueBxc3Oeie1Rj72fKeC+PYuuAQfVYcAm6KOB3I5wxw3V2FqrVcjB6nU5QcEK2SGjAqCiEeb zvhVBhfbaEPFItHdhC8AzjKJJEDzUR/Sae8+zs1yp0MioNC2NJU2b2T46uWh/mtXh9xUB59+OXzr OhOds7gvO5fNZLG0hSwRhR27oZjWrt7L6ehQ71Gd7+7u6jp7bkxNVY6sX2oWo3qF24bzIRSblpgG PofU1cluFdjW10zsf0jE4iCtbanp9Tbyni3DGIOs3JQcf73zSIvOfrtpF9ruZIPL9jVD0i5XQP1V 7PMo5rOrPxtCR2mP7aurPnjuj99cmZ3mWOuVNLCoPFZZiG/fPhx13Hft1HZ8gb2HVGBFbwwMGUX4 qKG9O8ymIaHXSnRGSBgbAknJDbX/uQ5Vt8EdQ5Un/3Lh2ZPKIIGn546b8ZWKTt9+RKOdJjyuLyEx sjcmrZFT49drnKVP0MpFKCVSvodIllC9MbGBVXGFTZI5fF7GVJhaDaY5JnAmUhXMEKo1hyKjuWY+ cNm0MtuuSAgmA2qTINAOdXp3aTmlifB6NeIDiKa/YK4hS4HO2huYJsZLajx9ZVBhc+ROZuvaJ5fs ocNOpWki23zohzmkUgTCATl94yHsmLgkK2JbG2BnuU8dtUCZAqcvD3pmskaX6kX3bTDaiTEyQ/7H CW1lo2uA5W7F4zbTD7higJI1nm2bC8hxjxKFjUMWcdFvXVx9b5gx1t19KIlNlztc3zKSDYDfIQmD 20YxNxE26Y0olwsOdXcHIwtDSDdP/mO/B2DkyCqqfq52teYP3+uINclwdALfEwzrfkif/+ABVj+4 3/mRYAQznAAWeRr9rYFJyCYzc+n+YEc+Ivk3mYbPzdFJCvoJlcJbn7NDl4DJllOtF68oB7lzC8LZ 1XbOMyC+SgU+gv82NoOl+Qwmb/2+mEetLuofi6zrb7Qcct1X5u2mWv9NFwEIKQaWm1JeyByfDavS mRUQwPBGLhyg4L0/Zm/lKwS7Xy5KNbYei6GyjaKIRQGCzMqZNbeXdUSaJOuX69A91m72cqe/5YS8 8ZxJk0h0Z230P1VdUvM/JgCES9tDukDZs/ZB5QNBvQETPULxOJdTk3P+Urfy9oIop7s2vr90TkVU sTHncjdh+7FbyZE4ntyLjXFoaSpr4qgNApTpAuyySTUydjJ6wCpUZgczQDQds9C/RDbAQo0Djm3i Z3sqYtU0mDFSn0TNCbfPI1dg909560efzaV2usVk0I6Lxqf1SpfOFY3ylTdut1sQp3aTllfK5Cce DAnMyvVttNdLQlFsm8B4ZXSjUtmoUMQL/TT3rE3vLRmNkukq5U/p8YoYokZJxwk+fGp8k+mOYdPt HWP8SeC7N5qObWTt2LTEIV0/toE02f81X6GkMsSFNlcAxh6ITX3kq54LRwaA/IrXhdeLTmcfXD6c CZS0bJoJu8X6mf6TQh1elxBhy02CdDseU39TQU5CvzyXXU/9S27EJdWZBLKaPIt8HpeETseGhq6A /0o41zC8BGA1PQCwXxsbrwKq9R5Z/KoNWZUiM0te5bMfc0D9XpzzT0VKUnTXDnqfvzCGW/JyJw6y 94axMIe+rfmr8i5J/2i6YJH0vr5+b9/mPxtMC2dNDb69FqtXDEEGByFCAGULIX3+rQ595deHP3+o eeJ1onhqqvhE/LMPAgIJ9eX0zAtIHk3ObUhdo0zcjztcnsL9+tpO1ZeRYpeQ0OxO5yjTYwB9eQtN kB5jeaj2k6GMTpvhM7bXMl2Zma+xz071Z0jbP3MjGxuckfn/hPM8ewEWTzihh8ffwjGfk7zDOFiS wLkD8km9j2UcmBA/r4F+6P2fPj+lx+aZGqT/ttXFc4MLvsHeFz+dI2huuSapwQ4fvLmHx6f65ewP 5BynaSmyjsKkxx50UkLNneN4ypqzP8cP7cPfc/dgP7vwAbc5fj7oeCsQpxC5/LT4PexbcJ5fisH2 9z8Ae7dXWbAw6gfm/yiIPnzvvqYdut3P/W1dkXNNX+i8nr3u9GRG0f+aXkfLna/3L6ey1A11N6bq 6lY87XWszXcWBSnABTCXx8svWD0yjRLkoUVFJaPCvp/O9lG3f/ywffjs0xFK3GHP5yffpXigX5XT Rg/+rt6j7lf7OwYNHKWzsqGtoE7Hxe/p6oXLyo9azqRaOgQNXqYXrj59snCl07We3vsMID3BJNc3 H2huTk5pJux/Gb05WmY9sq2SZ9Mb9FvhPv96RaacJONIdlqTFhmDJ8LNC8JwJzZVWnOKDha6Zpbo VudKMS6Xo5LC0mw4ZsdelDutissr9+tKTvDrj2/t0Jx3qa++IDaEJed7a8UhrpxNaUeQUCSJER12 dw9J4fQphgjKGFlx/kILx9VR9NAmN4UJn9bokubIkf5p5m1hpiYCJ1OuL3TXGSDJjmFcu0bbKtc+ 6C/C67Lpx3shttJrHbo3MElowG48NrlkhcLPvMA57+o4UYHeXq5aADC53oG4qNwbvoh0vbxJoGfy 7Z3yRuntZuBk3zheGxe141KIcSLLzHKgVgE2nE3ZYBObHCIGgJB0UzHbkLKhZexBgZP7BL1VLO5L o9InpPyJxWudJEsKiqXBj9BKlyYxiKDL1V6/JC5rz5i3VXaVpMzcCLAz8TaarTJjvj1xfFYVGYyj bYUPxH0BlLl/EEgf/4qcyaaxxeuMW7bc82ksXwY7lK1xXMKPd9kJnf8XFj3FGSKNNimv7bSE04kE EAJi79P+/oGBbgD99MVjV6+GqTD52f/+T0ujgA4CO/Za6SpKVMm5jXWL9n8CCAk1ouIFstads24o 0vAs6/R0jPMFgW9hvq5SYMI+2AWGMyDmCp+OGYH0wN94xikuUkUMx8inFAidJXZSDHHixo56qwGM N3mFtf10UlS6/JKRQbg2QJ7+CTyQCafTr0CkMlwGrcsg5Nwz+UEMRjDKVN9MFmdydlwitUnL9uyB tIK/k1U8QLVE9Jd6GGi5PV+3pFMDiwtpmzPJYzdAH+6vvZrjqmQL2OG5nFM7f/Is1ybl/oG/MPVR PXr1BYAyALRV91333z/9dz3FY1kXZUgMOeO6sX/aSX24LvG+/oI+u2ZuapPDZNhDpjtQ6FiZPL96 Sefgg3hiHpPue8mj4pUAUdBr2SedJZ0Xr+qI+CT+RGHJwgmUbcR0a5kuUksY0q3bXtEyNI/nPio3 ghKUuwXRlx12NQSQyxqk62PWuv5qe87fwaeTsOgrKX010bE+7AVzO/wJphod4WqMaD5aRxdJp4MG sxkywDoSBSgmyvdfGoR70qB28MKuLYPHbYtQkOWMR/QkY1bzaEp3G9bmVzmpB19j1YAf9fK/g7BN HSmj7cYsehLjEWRDgcVx29XqTe0fTFnmVr0VifTcnR+V/zkMpHvh+lH//Kd8/gedmRDoE33B0pi9 04Vmjdu5SM+pRHu/f1l7e3zOisFLlwdbM1O7uqvKpzEm1gPRByYxMXBXOTzmv4931iiNp15iiCfw tJVXXlaQ/LYNZGv6Gq14eK6iIDm2p7O3/PjIn5OMZ+BY+bCN5K4sHLxyCYiEhI4XlKPgyHOPRa6i 81sjv5wpxLFx345UmfNW4z5d4uxyD1C4EaMKTgp78RYV+ZI10fk1J5833Nv5XpE7XYB5dt6QkEIF 9c8bQ0oKSO19KNqnsP+5aE/hzw44zZa6HiAz/klxrPv3HifOpS4rxOlY+FjkNO6R8zAxVp2Keweb 8YLaWt2an5rC/2vGNCMfBxR1bLEqi39SVemZlmLu/cbiV20jJIXWkBwdJpvVNzJr3uSSXDpLfMPW mXls0wc/MjcD07G6dTE5+eqIdklqfnncRfA71hx7R8jPyzxCvMLWgmK+aP1toa0AKxbPnWn8c/+C tbUY+014aaLPDS1DwbB5xmqP6k2ENJdquhYXb2ioj8bE01OdW+MD+zxrTPLwSfR5Os0d9VycFn+Q HtEOOQOVBqDlGgt6knkNDTa/s/M91yHdkMa5FDlAa4Rxtf9QYNh8xUjiJY5juqER90Nb53wYzbyG no6iRnv850zHfdElhMQnnjGlJfjgCyweYBtQgXPduviUck8s9guHHvlfdKzZ12Oy1RH3v6OQBXgc PP87aKAdPuD0nzw4SktjhcQ5Vg9uENuqsx/e5Hj1b0CAJNFbVKBzICpoBgBpfs0wbippECZ1dWql fzSkzBLYl3bFhkpd7F8sZijhJXJ//GE98laHEybVAHq+uO0vhy2e1GZ5Lm7psG9pdY31Zs6dmiVW evk9O52OlVtmFiUvokRK26jRaLUoUYpuSvdUO7d7BZEjvPys/4/HbEypD8kXGN02yCFtFi5b96Lj 2fSSEGnKvePzRLpvcOeQvV3c9vaQ7mm0za+ED5fWpWR/+yMi5M02AG4Ep9ohtyxS1kaLwq81xXv/ DGkva3EqV/qo3I6EBtCxj9Xiz7BJWNpotq8UxvC3d7S3d8RjeLBf3/9Gs9OMP+/1wHysuoXzg45J t15LvFbZb44fGcDXpr8JRjKRQa+93UIYtbJ+ROVHZ/Y/nczM3+aBoy4rLMyJ545opN93tWfw6UXy M8KbcovFbztJmp1lkKkdHHkgoMnJJWQaWnGOptb9sGc/W7LGCgy15LM6e6rTm9CU8ESq2nXTkGRi Yw1taS1POvfEL56gpGa5bxgxT93jxzTFAm5h/XrNmWGMNP+t8NirV6M+LOqoIScl5dqVyzggwvyH MVqx0u9CL4M2HmbhJs6SJTFn6d7HjVyAl+ethbVnfTEJrQKkN/6p/PUXxz1JiJEevwXV0OTyfrox xIEiveGfGhwQ6phw9U4GBJZVwXBx94yi0yScpKxCpXQwP2kQJYqyTfIO3FJBLrZPIAAw074Pm36j PqT5Ki322hUH37yc6EL9DhuE1FyoCgmFT0xIxuk2gVLi+LObmPI5yeSdvjhcZPPLff2+xNfh/S49 C9ApSXOtQzuS1J0b17U7+uijtRE+0woLCPLWlDub52HCthV5EdOsqigqPzNomqFhD+Tp72/PilRP a48f7i60jYqozsnip9NxOS6bPBXU97y6owDhawp26mH/Wf3BjfWz7PWqt1+tnVNYZvw2gbc8Esaa tOyloffzjwDThmZWUvhKb/NZ94yk5P8TZWmexlPHUu5zIfYQo/ceR+b7WIXqtpAvrj/XHnCpjh8Q QB1oLgr69YpruHlhH5BnvxPy3STrrQ1gaqyf3S8H8/NJrn29GwP/eTRMDSAw3jgbMKFUo0Cc1iAF cUZBFik8eEZhn1d3hj4jC/G0ICejyRUZZxZMl+NQM7QGnW8tSHgU6hDlsnm7S2qQr5lYOpx/N4Zq e/gPqrTwHMbOoFxqSRyre5FAzDG8Qhx66SXwSln4/6M1Uo8KlP4CC9LFRFptfEaSN7SC+9f5D4dh eg0n3KN9XNr8CmfqG47BDVHYdmtS/qmZ9bvJtv/l72GZi2VZ+BR8yQRyPxldqqCwN6QVpB8bdPsn YpgFkWnOrCYDJcG3ZQHUm3ff7lvRP/7i1eD4dmrd7m/78XlwWCN3+1FMdRauf/Z9247Zd9KZdzvi 3AVyyyZB5kX/yRUOG9NvMOHhrOZu9kzQTezuBKZHxITTFFR9s/lxjFvRv+8smYD3oMq32cvWP/1E T56jN9nbQzb8axFzT1Lidq52pLjRXVBSMN0/En4KNma0z4eBVWObXo2sqtCNbysnnXYr3E1dd+1O xLUbxGvTe/8zsqOYVZkOOFREqzto9ub3OvGVFkWwkJBDaxLGDYI8EVsgD0cziCIV1a/SD9Ge7gKK V1bSvQkxBKEfw1z9YZf+xU/0dTs6UWGdGXM9DYnLfFtAteOQLbUoeCk8mSSCmge1KOQXAtZAQ0jw ZAdz9AJDCh9lX/Q2E4dMk3a3mCRSQ7ooqLoneEsB1vz/nSxX/0A2c9P/5lg+Bn+jitxFAf69iXm9 JSF0LeBOj0v9xrpQ08W3sLZyhq2rzAT7zp/4ysTmEFfS2BmMXXA7yGTdYxdUER1QMjTVov3b9aTb cYwIYhLjQuz1ZyMWjlIsgU6sy/uFzWIedFsIcm/vMBcfsjF5EUB6y3ImutrI6Sjbn/VX2ddvpHTd rgFisZAaq5YuYKEFLvO+fBULLdoTTEyAiYJmheJ84Bp7Ic8ooNcItdiQLBA0989AFS4I7d7iOt7K EmMuYwLY37GeVi4Y3JNaaAcFAUOtXCUDSDDpoNIEKpPIicvwHhS9L3xXMcifqxYi66oP2WcjMezN CcRb9R+DmH++YDEO+0vd27l89AFTtDekcW1UyqnYdz/0Ds/65mIvgYSBDmOR7eAEgAgksvOV08nC IvJFBLY9mOnRKOY8zJyw8xaIVD716n4CKJc0VFdzqVhAeovBNuEt5kkQkcOj38ya2HD4w+iOrJ9P JVASnmI+RQXKrd4HPfYjUvl5t0Z3bLIHd2y4mc1jENkzwe8wXI4n9z1mKTgYTfuNb2LjgysbwLgK HocomEG/c/T1kWPeBc2+0Td/q/TKg7kV09lBqISZoHeYhIfjo1j06Iqqe9kzPQkPqqsGbPBwVG20 JA+rZv7f0+xIEwDGY08ucz4zIjfrnKZMNSwfQyAfYO/os5/OHi5Zv6EIllI9kmabE8AJXnnm7EqY IBr3+d5fbhbWBZxEp5JE+6KLpfhC9s2Tm+hR42JSBMHl4bOjalLmF6Uzq3SrdVRar8jFkZbh0bgT IKleublFuUGhqcWWMrcej3rTyfYywW5mbs56jx6kydS1dyuTTIIYHp28UecjxnzPb6+7k7V4R9iT 6liUPHv3vVUN1jUZ9z2jbn6OhAUs+XIzysX6XHFSi+2qnQEc5N1kYsSzrwrXqvDmkTU7HvQVZzGv H9ghoiSk4SYiQnxCRl7z3NX+W9bkZwn7mQWhGwu1Kfl5pCQiCUlgSzBNbU4m8TS1vJiGIlPHkOvj nfAV1nusp8FESspCI2n2ycqi6jSROLzMlJHyp2+cf3DDU6+88iptNLLLZlzWVCijkWU2WiLBe+Py it8VJX+3dZlPb4+RdTFMEBNXOIDREjTyy/pu/qeF5sHqOBEvyAs8MoQo/vwkcXZv3xn0Pz396Mf2 qvZvdWoNptZbbRVv9nOJka+5aicdB4yaXgUUM1L1+kNqVkOpjLzON6ojgWPpWdZTJ/yIwhjkVIcF CiNPwETdv0Nq+PYKQgUEyIWMd0CC8IUXu9paKZG3/RacvLk1D6CR2f7McwTQcbwjHyJ0fTI/LyYd +GIOoXsN2NOMoih15mLjwOz/5YWKPhtabRiHFteayGxmabZ+Mut3FmCFsQBoVpr9lQXAnO0IDOAJ xgnzsjsNGug4iudvspUydXqvWYcx82sMrASsNGplHCLlRYpaC8oPSi+3C/TnpNouZHq/WW8KUXx/ ZyAP6repk0AOiWOJFxlQflMF6tJg0bJge0hIsX4xkYRMJwDqWzA0JpX8dgsaVKbGcViK/giEan+W XWf5MTx+pHmbLFKrHyBtNBvMrUxqHRQWVBrKXhCipUkIhfJQvdCeb5Pvl2KcWU9x/mcLB47D3wBf C+xfTQqp09tMlKYIb52eCuk95kczk2y62H5pUkakV+t/WahKsV8IYW5Jb8D8yIC0xH5oYWkqzD2m l0yK+dICyCK4AQ+9BAh/k7X1ew3IFO3Mb0IO42zDjX+g3Wt6Ean1mM3FKV1rO6oBNXo9C1Pr34b5 YhMzwjwLqdFrIN76mIbT5urrLJAKr9SJh3mNMvO2iy0MVndir/Exv0IaaKLT/DSx95sQ0lNKpian 0nbl4Hhfw1JndhiHSqfaXvM0k1LM0PWNSJVZakGxO4MeBCn2Nylsv9dqTbMRxFR56sxyzScHfs+1 y2hx2bPPTn6gufyo7/1ib4J/bDgpDKaiExlhAXxkNvKVlhTIkNoNM+KH+yqR1ytH63xqEYjE/QQ8 zqMAK8I9JSAc4+hQOjUaWGQhXWcN8Z097/EWsDZhnb8A48BzxvKgZ8TOHY7ZfJXcMuuosaTGHKPc gn7KA3TdVGgdhWUa1lMjzHCRwegdXq/JWZJXnVmnCXVUfbz101Yb3N6hv1JWIgxcZ2AZrYWcCGuw sV52J1goNY63Zat58TGcb5Q1Mkg5fJlvdhQIjxcUeoDPtcyBF3ozyhmPHArluiDjbDJD5z1QQ7OV ReZMgnq/0ILEuzifdvSh7GdkF9kwvdIDMXwGbWktL8ecdgyEVnJEpl5C418nHSHOldf9NM5He5Br OdXBN9RLs0fdK9uykA8lrTppJEoKvkANB2ko1Y7Z/nXScZASy/WRIS3fQLu4Rr2eG2nF25ZyWoSt p5V6MFIZlTYm+ZCCnZeOq84nWTAWjOcQaUInVtqarzMOtWKd1BInsZK2l9dPF47r2LhUVoPyS2ot r2yXGKM2glZo00Kb4TB9sVr/Qo9brLeXlVgYaBy9Ov36FlOQIFOTLB8ewEtcyq0s5yhlkwYODEoP Et66JEEoOC3999PHMtCnTZQ2fTzjwO/Fctv3ZzY8x+pZyov58ZY/sF8rSRjlvowpLcvke8K6rJ+K BVKcokxfPIqFEXgl7OcGHlTVxxx/QAOHe1CZU4f3lzrGQP+e0NDPH+DBKRaWYhb71yjLeDAig7uh e70PZXXvCXU1/fwgc+uVAC8fz0CxT93PN3foS9JK8foqW6/fi0lNeXvtfOk5hA82nZI+LeFnuGs2 dfx8+IZ6mPZ/YmEmXpAjWdd1lJvt0Fo8Xfh5GBT5lz+eVrSYM3CabXqqtkK9gRwfbl8LZR4M1oSq 7b0Y7qf85mPbYHJGpw1prVhHSao7f5iFszTkUr7q80vMap07LcZUe0u1ldxpkzLcvhf5mN6wrFwf Pvb9Xh3+WXWhu4sKkLfLAYwAPk7ik+EQe7UKtqMQOgOcAEtT0PeUmIOSMlYdVNSy8aBmX247aKjj 9YOWvnxx0OMWoQ/69Bd3HMxQLbYdLmZ/AZ8q46gf0xCZ0KsvkocdfI16Oefg6/hy/TvfoEhu/Rz/ S1Ej23gqJrLfuf7mmi5kjXQtpdm57z+bTA9G5qndN6cCPkQmhmvuhc5mdMXTYj3dpE12J/Ttuvff MPGr56ePh9Ozk6jy4+ry58XyN7NgBb90yr9A7UEzi2lvhLR5jnsRVV72YlwMIXBgRdMV55Tn5II8 Qf6hZQWkq6tmt2IFBmt5l+aKd1hL2yQ1da4uokK4QMSXCAmH3F2D6wVFAkxm7S0d38vQy6WEj0BO UlZ6bEh4IXv+8TcWxOjUOScfOVz4ke8SYjZ928nkePP0SAqzheM9MUJbFueaU3r/D3UxtuyHMbwk q6BsoMCEZREUJAw8glCzzT7HnHPN/RXnves7v3mnpRsRTgBAhAllXEiyomq6YVq243p+EEZxkmZ5 UVZ103b9ME7zsm77cTpfrrf74/l6f76/vx7j8AQiiUz5RvI/FTqDyWJzuDy+QCgSS6QyuUKpUmu0 Or0hgY9auMlssdrsDqfL7fH6/AAIwQiK4QRJ0QzL8YIoyYqq6YZp2Y7r+UEYxUma5UVZ1U3b9cM4 zcu67cd53c/7/QiK4QRJ0QzL8YIIoCQrqqYbpmU7rucHYRQnaZYXZVU3bdcP4zQv67Yf53U/7/fT eFhtdofT5fbx+Pp55Q+AEIyg2MLhBIlModLoDCaLzeHy+AKhSCyRyuQKpUqt0er0BqPJbLHa7A4A EASGQGFwBBKFxmBxeAKRRKZQaXQGk8XmcHl8gXC5pWKJVCZXKFVqjVanNxhNZovVZnc4XW6P1+cH JBY1j6yea5/7vuJkRdV0w7Rsx/X8IIziJM3yoqzqpu36YZzmZd3247zu5/1+BMVwgqRohuV4QQRQ khVV0w3Tsh3X84MwihdjVlRNN0zLdlzP58eEMi6k0pbtuJ7/rReRZEXVdMO0bMf1AESYUMaFJCuq phumZTuu5wdhFCdplhdlVTdt1w/jNC/rth8AIAgMgcLgCCQKjcHi8AQiiUyh0ugMJovN4fL4AqFI LJHK5AqlSq3R6vQGo8lssdrsDqfL7fH6/AAiTCjjQiptWrbjen4genyVCAzYrPcnAbBZ7wEJZVxI pTMUWcTriz5udDqJlx4GteodNXpDAPuj7+WFlAvqGbtFsQKPjzfn8CryVTUgKyhdfWZHwDv+ZLbL a4xVfu7WBK78QvvPfLmY+nCDuUl3rzZD3RNQp9x1OtRDTV7YV+oNHZCo1AtVEMJ88p1oBn+L9SuW qf6mB73Kmj+TG3ydj+wJ4YILgtjAxliPfjfw1m7I6E8Fg32cgFCOnLCOL6ld6LCIaQFbF8Nlx1bM 4z4HtCIh36XsyrurEuazf+zxAj61e0xiVC5kUGCSoWukYFYFin5KfMQdGPdDxqXjHYMcY3rOnhzh JvPFTI9JkKdTxk9Vl4uqX61K3L6KxsxplYBJSiSL8wo3iEfGbsK9YsBsXb00RuNIPtK4pTicBWRz NFvrSaUmUb2JopmBUWtGduC/9WwWVixuBX++gcMCqRLF+hlTe3w37dIqKtZcLMgpPj9VXsFVJOPU /Q+9zBCpF2fSscXi3XcNbq26g2Jy3JoW6nQA4Uvb3m1wLk9glVgC0dSwypYvLsYlI6Z6ZFkmRBF0 uCbzw6NIOi4ezvmNQZ0MvlL7y2QrQ1gNeP9c3QHJFKjxN7qtEc3uyesFRI+7rSe4YJdaq6GbKANs CsoC+r5DlwumYebwlCvOLpdi2p/6ZdJukLBXIUwB2ISkkC+rvC5MYrbsCWXkaqQVDgHbLjYgb0RZ mHMp29vOA8sMUkAeSUwrML647/T8F7JED/SMR4/MdkVOAjSIlLBjC/ncRJFjvNfhAINDHlt1VvtV HaNw7i58lXKv/e5etS6Z27VW14oDknsEuwrXfHgVKR5A29RZSD9htuZ2uclimk4McT/uw3rUo8S0 9K0gJyC3Cb9+tI3JpOdyfKeh1dVVA6QzwBiaNmsk3ep8OrzJKLHbC5es8nEjGUn6Z2M9TdVUtUyV /uGe1DFE2btfstDFULvZhF6C6MiclIBoUrDELXoQHKekoGy8KBJuYo8SrazB3lCfaryNW/6Hxc9e fr/coJVnwDY+P3pYXtF8jskfOqWe1UBJkAfxiJuHiqNqSYu49fDciuKxN62WWzACOJE7DVHKwogh RTtVsSjKC0duWrqVIJ02kDmg15+yn9sWVo4nysG57cdQJfmZU0yoU1ZCvWWPXqc3fw6uSZCxym2O 9/m7PR6Yd0LX/s3THx31ZsLvqMIoJNX+yn/JVrx4ABOAwS5WSe1KVZEswwZ/cnsca2UWapijyP3s aaoqIWvDDjScUo81A4epKwOSmP9Zvb9JJSSxVMELSl/dykgE2qUKjpaDy7m10dr3rT8g7Xir35gT Xup8Snrp/m0NyO4KEyvKkavPBXtGlNZ6aS+AzDob5bYhKjCHRUhiXgL5z0hEutP2PqJZorxoR5dx MCSPZiOcUSbkZ3tk9wtFCZDNpFHdMLnH85ZtJXSQ9i3ue/UeAupfEaj/ANA0xm2eIsV65KYxXKA9 UU/JxZiUHe4kDpk31+hgQhRz38Z9bXp8Ikuy5A+DuZZ9TAnZoJXrQKHvSAceBSQP+gdnzXcaCC/l Y98WSKFlJ4igoGQ0u4jr2uD5nbqNww65sEDoL3z7RKGHwf7EbwdMV64FGUOf4CsmIKUMOOTmmAOi O6uTqE/K6DkFJl2XUs9lCF9wW+aT0nzgmE7VZtm7QuWKE6MgV8+xyMBYjyjMPkr3+vj9m9CViB7H rYlBHTbd/riTuu6RI1K4cRlSkH0/75XR4Udi2lusB7IJ+hO5zrd8fEjPWJVYlv/hkahT3SuAug8M 2s560X9ry6H+uyHPqcwjQ5U68D8oUcUv/nlnFEuNlRvFn16ZY5WoNoduy32Am5oLjzhRbkoD5tWE 3mPX1RteSF2QHACoYxCE5QNNh+MM1eaUHX4PMHBgq0AVaqRzeHqJJbkgfh5yFcHdWJSuhtCtwt1f /+0i1u7ydyfVq6EaH8iVP1gQWzvFk5YDVhTV5tInPn8JIhzXJlj/eYIyxZZLmP0uf0KYLWXbXG0z z/d2bNLWUkgn91Q/TfvwkzuUYKjJp7Cn57Lmz8IK/qRc5rAKfBM7w2Vg0Z/cHU1SmCYPFiprq3ep CWbEtRJPO/x67t2YdgHVvMCntRIAfar5AfBbxn6aonSr9iiBcwzaNLVPHvW4ipW9sv0WHMHG9f8G jCYdiTIuXECoNsC9gyWWjpFUm0dsjmx6ii/sJPaft9Uf4ppNIP2UqDZPOah2zN2DN2Hn+ZHFrUri Bi6fGwcN5QG8c2pvrRdmVxz0lsKRwr5Qwy/j1C8+HptsKONCquMx2/8FB6yBV/T0llF40z/GW0Cq 0o+GyO36HNgYAteWUR/538JIlTEKA5jATgPPP8QbVut5ghP/W5MPEz0HKoFKoBKoBCqJomEwQWd9 nsGZeRyo5p59jiG7KTEujl3VabyHOX66kwhlXEg19C6AhJ6W82rhLQ5zDbzPGFJK2dOItwjZbs6t kJGVUkqpUsFlQmmtdelPCF1b8GMkDb11bB1bx9axcQR4JSADld+9/t69//28dtIQyriQauidIIkQ QgghhFJKKaWUUsYYY4wxxjjnnFeTJ+ecCyGEEEKIEltIINFTzgkppZQl980rKFEqkFBKKaW01lpr rUv/QPJujH5LwfnDtRYQojfmduO8xU9LUkPvCCSUcSHV0DsBEsq4kCpzm5NTBhASyriQqmdlMJrM Mh8jgIQyLqTSBqPJbJ0vSfv/Fw== ------MultipartBoundary--qLVjWd2mJZuVXpZ7T5d8aGIIY8W483Ad8cFONoagZS---- Content-Type: text/css Content-Transfer-Encoding: quoted-printable Content-Location: https://vulkan.lunarg.com/doc/view/1.1.82.1/katex/katex.min.css @charset "utf-8"; =0A ------MultipartBoundary--qLVjWd2mJZuVXpZ7T5d8aGIIY8W483Ad8cFONoagZS---- Content-Type: text/html Content-ID: Content-Transfer-Encoding: quoted-printable ------MultipartBoundary--qLVjWd2mJZuVXpZ7T5d8aGIIY8W483Ad8cFONoagZS------

4. Devices and Queues

Once Vulkan is initialized, devices and queues are the primary objects u= sed to interact with a Vulkan implementation.

Vulkan separates the concept of physical and logical d= evices. A physical device usually represents a single complete implementation of Vulkan (excluding instance-level functionality) available to the host, of which there are a finite number. A logical device represents an instance of that implementation with its own state and resources independent of other logical devices.

Physical devices are represented by VkPhysicalDevice handle= s:

VK_DEFINE_HANDLE(V=
kPhysicalDevice)

4.1. Physical Devices<= /h3>

To retrieve a list of physical device objects representing the physical devices installed in the system, call:

VkResult vkEnumera=
tePhysicalDevices(
    VkInstance                                  instance,
    uint32_t*                                   pPhysicalDeviceCount,
    VkPhysicalDevice*                           pPhysicalDevices);
  • instance is a handle to a Vulkan instance previously create= d with vkCreateInstance.

  • pPhysicalDeviceCount is a pointer to an integer related to = the number of physical devices available or queried, as described below.

  • pPhysicalDevices is either NULL or a pointer t= o an array of VkPhysicalDevice handles.

If pPhysicalDevices is NULL, then the number o= f physical devices available is returned in pPhysicalDeviceCount. Otherwise, pPhysicalDeviceCount must<= /strong> point to a variable set by the user to the number of elements in the pPhysicalDevices array, = and on return the variable is overwritten with the number of handles actually written to pPhysicalDevices. If pPhysicalDeviceCount is less than the number of physical de= vices available, at most pPhysicalDeviceCount structures will be wri= tten. If pPhysicalDeviceCount is smaller than the number of physical= devices available, VK_INCOMPLETE will be returned instead of VK_= SUCCESS, to indicate that not all the available physical devices were returned.

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INITIALIZATION_FAILED

To query general properties of physical devices once enumerated, call:

void vkGetPhysicalDeviceProperties(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceProperties*                 pProperties);
  • physicalDevice is the handle to the physical device whose properties will be queried.

  • pProperties points to an instance of the VkPhysicalDeviceProperties structure, that = will be filled with returned information.

Valid Usage (Implicit)

The VkPhysicalDeviceProperties structure is defined as:

typedef struct VkPhysicalDevice=
Properties {
    uint32_t                            apiVersion;
    uint32_t                            driverVersion;
    uint32_t                            vendorID;
    uint32_t                            deviceID;
    VkPhysicalDeviceType                deviceType;
    char                            =
    deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
    uint8_t                             pipelineCacheUUID[VK_UUID_SIZE];
    VkPhysicalDeviceLimits              limits;
    VkPhysicalDeviceSparseProperties    sparseProperties;
} VkPhysicalDeviceProperties;
Note

The value of apiVersion may be different than the version returned by vkEnumerateInstanceVersion; either higher o= r lower. In such cases, the application must not u= se functionality that exceeds the version of Vulkan associated with a given object. The pApiVersion parameter returned by vkEnumerateInstanceVersion is the version associated with a VkInstance and its childre= n, except for a VkPhysicalDevice and its children. VkPhysicalDeviceProperties::apiVersion is the ver= sion associated with a VkPhysicalDevice and its children.

The vendorID and deviceID fields are provided = to allow applications to adapt to device characteristics that are not adequately exposed by other Vulkan queries.

Note

These may include performance profiles= , hardware errata, or other characteristics.

The vendor identified by vendorID is the entity re= sponsible for the most salient characteristics of the underlying implementation of the VkPhysicalDevice being queried.

Note

For example, in the case of a discrete GPU implementation, this should be the GPU chipset vendor. In the case of a hardware accelerator integrated into a system-on-chip (SoC), this should be the supplier of the= silicon IP used to create the accelerator.

If the vendor has a PCI vendor ID, the low 16 bits of vendorID must contain that PCI vendor ID, and the remaining bits must be set to= zero. Otherwise, the value returned must be a v= alid Khronos vendor ID, obtained as described in the Vulkan Documentation and Extensions: Procedures and Conventions document in the section =E2=80=9CRegistering= a Vendor ID with Khronos=E2=80=9D. Khronos vendor IDs are allocated starting at 0x10000, to distinguish them from the PCI vendor ID namespace. Khronos vendor IDs are symbolically defined in the VkVendorId type.

The vendor is also responsible for the value returned in deviceID<= /code>. If the implementation is driven primarily by a PCI device with a PCI device ID, the lo= w 16 bits of deviceID must contain that P= CI device ID, and the remaining bits must be set to zero. Otherwise, the choice of what values to return may= be dictated by operating system or platform policies - but should = uniquely identify both the device version and any major configuration options (for example, core count in the case of multicore devices).

Note

The same device ID should be used for = all physical implementations of that device version and configuration. For example, all uses of a specific silicon IP GPU version and configuratio= n should use the same device ID, even if th= ose uses occur in different SoCs.

Khronos vendor IDs which may be return= ed in VkPhysicalDeviceProperties::vendorID<= /code> are:

typedef enum VkVendorId {
    VK_VENDOR_ID_VIV =3D 0x10001,
    VK_VENDOR_ID_VSI =3D 0x10002,
    VK_VENDOR_ID_KAZAN =3D 0x10003,
} VkVendorId;
Note

Khronos vendor IDs may be allocated by vendors at any time. Only the latest canonical versions of this Specification, of the corresponding vk.xml API Registry, and of the corresponding vulkan_core.h header file must contain all reserved Khronos vendor IDs.

Only Khronos vendor IDs are given symbolic names at present. PCI vendor IDs returned by the implementation can be looked up in the PCI-SIG database.

The physical device types which may be= returned in VkPhysicalDeviceProperties::deviceTyp= e are:

typedef enum VkPhysicalDeviceTy=
pe {
    VK_PHYSICAL_DEVICE_TYPE_OTHER =3D 0,
    VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU =3D 1,
    VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU =3D 2,
    VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU =3D 3,
    VK_PHYSICAL_DEVICE_TYPE_CPU =3D 4,
} VkPhysicalDeviceType;
  • VK_PHYSICAL_DEVICE_TYPE_OTHER - the device does not match a= ny other available types.

  • VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU - the device is typi= cally one embedded in or tightly coupled with the host.

  • VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU - the device is typica= lly a separate processor connected to the host via an interlink.

  • VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU - the device is typical= ly a virtual node in a virtualization environment.

  • VK_PHYSICAL_DEVICE_TYPE_CPU - the device is typically runni= ng on the same processors as the host.

The physical device type is advertised for informational purposes only, = and does not directly affect the operation of the system. However, the device type may correlate wi= th other advertised properties or capabilities of the system, such as how many memory heaps there are.

To query general properties of physical devices once enumerated, call:

void vkGetPhysicalDeviceProperties2(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceProperties2*                pProperties);

or the equivalent command

void vkGetPhysicalDeviceProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceProperties2*                pProperties);
  • physicalDevice is the handle to the physical device whose properties will be queried.

  • pProperties points to an instance of the VkPhysicalDeviceProperties2 structure, tha= t will be filled with returned information.

Each structure in pProperties and its pNext ch= ain contain members corresponding to properties or implementation-dependent limits. vkGetPhysicalDeviceProperties2 writes each member to a value indicating the value of that property or limit.

Valid Usage (Implicit)

The VkPhysicalDeviceProperties2 structure is defined as:

typedef struct VkPhysicalDevice=
Properties2 {
    VkStructureType               sType;
    void*                         pNext;
    VkPhysicalDeviceProperties    properties;
} VkPhysicalDeviceProperties2;

or the equivalent

typedef VkPhysicalDeviceProperties2 VkPhysicalDeviceProperties=
2KHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • properties is a structure of type VkPhysicalDeviceProperties describing the properties of the physical device. This structure is written with the same values as if it were written by vkGetPhysicalDeviceProperties.

The pNext chain of this structure is used to extend the str= ucture with properties defined by extensions.

To query the UUID and LUID of a device, add VkPhysicalDeviceIDProperties to the pNext chain of the VkPhysicalDeviceProperties2 structure. The VkPhysicalDeviceIDProperties structure is defined as:

typedef struct VkPhysicalDevice=
IDProperties {
    VkStructureType    sType;
    void*              pNext;
    uint8_t            deviceUUID[VK_UUID_SIZE];
    uint8_t            driverUUID[VK_UUID_SIZE];
    uint8_t            deviceLUID[VK_LUID_SIZE];
    uint32_t           deviceNodeMask;
    VkBool32           deviceLUIDValid;
} VkPhysicalDeviceIDProperties;

or the equivalent

typedef VkPhysicalDeviceIDProperties VkPhysicalDeviceIDPropert=
iesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • deviceUUID is an array of size VK_UUID_SIZE, c= ontaining 8-bit values that represent a universally unique identifier for the device.

  • driverUUID is an array of size VK_UUID_SIZE, c= ontaining 8-bit values that represent a universally unique identifier for the driver build in use by the device.

  • deviceLUID is an array of size VK_LUID_SIZE, c= ontaining 8-bit values that represent a locally unique identifier for the device.

  • deviceNodeMask is a bitfield identifying the node within a = linked device adapter corresponding to the device.

  • deviceLUIDValid is a boolean value that will be VK_TR= UE if deviceLUID contains a valid LUID and deviceNodeMask contains a valid node mask, and VK_FALSE if they do not.

deviceUUID must be immuta= ble for a given device across instances, processes, driver APIs, driver versions, and system reboots.

Applications can compare the dri= verUUID value across instance and process boundaries, and can make similar = queries in external APIs to determine whether they are capable of sharing memory objects and resources using them with the device.

deviceUUID and/or driverUUID must be used to determine whether a particular external object can be shared between driver components, where such a restriction exists as defined in the compatibility table for the particular object type:

If deviceLUIDValid is VK_FALSE, the contents o= f deviceLUID and deviceNodeMask are undefined. If deviceLUIDValid is VK_TRUE and Vulkan is runni= ng on the Windows operating system, the contents of deviceLUID can be cast to an LUID object and must be e= qual to the locally unique identifier of a IDXGIAdapter1 object that corresponds to physicalDevic= e. If deviceLUIDValid is VK_TRUE, deviceNodeMa= sk must contain exactly one bit. If Vulkan is running on an operating system that supports the Direct3D 12 API and physicalDevice corresponds to an individual device in = a linked device adapter, deviceNodeMask identifies the Direct3D 12 node corresponding to physicalDevice. Otherwise, deviceNodeMask must be 1.

Note

Although they have identical descriptions, VkPhysicalDeviceIDProperties::devic= eUUID may differ from VkPhysicalDeviceProperties2::pipelin= eCacheUUID. The former is intended to identify and correlate devices across API and driver boundaries, while the latter is used to identify a compatible device and driver combination to use when serializing and de-serializing pipeline state.

Note

While VkPhysicalDeviceIDProperties::deviceUUID is specified to remain consistent across driver versions and system reboots, it is not intended to be usable as a serializable persistent identifier for a device. It may change when a device is physically added to, removed from, or moved to a different connector in a system while that system is powered down. Further, there is no reasonable way to verify with conformance testing that a given device retains the same UUID in a given system across all driver versions supported in that system. While implementations should make every effort to report consistent device UUIDs across driver versions, applications should avoid relying on the persistence of this value for uses other than identifying compatible device= s for external object sharing purposes.

Valid Usage (Implicit)
  • sType= must be VK_STRUCTURE_TYPE_P= HYSICAL_DEVICE_ID_PROPERTIES

To query properties of queues available on a physical device, call:

void vkGetPhysicalDeviceQueueFamilyProperties(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pQueueFamilyPropertyCount,
    VkQueueFamilyProperties*                    pQueueFamilyProperties);
  • physicalDevice is the handle to the physical device whose properties will be queried.

  • pQueueFamilyPropertyCount is a pointer to an integer relate= d to the number of queue families available or queried, as described below.

  • pQueueFamilyProperties is either NULL or a poi= nter to an array of VkQueueFamilyProperties structures.

If pQueueFamilyProperties is NULL, then the nu= mber of queue families available is returned in pQueueFamilyPropertyCount. Otherwise, pQueueFamilyPropertyCount = must point to a variable set by the user to the number of elements in the pQueueFamilyProperties array, and on return the variable is overwritten with the number of structures actually written to pQueueFamilyProperties. If pQueueFamilyPropertyCount is less than the number of queue = families available, at most pQueueFamilyPropertyCount structures will b= e written.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pQueueFamilyPropertyCount must be a valid pointer to a uint32_t v= alue

  • If the value referenced by pQueueFamilyProperty= Count is not 0, and pQueueFamilyProperties= is not NULL, pQueueFamilyProperties must be a valid pointer to an array of pQueueFa= milyPropertyCount VkQueueFamilyProperties structures

The VkQueueFamilyProperties structure is defined as:

typedef struct VkQueueFamilyPro=
perties {
    VkQueueFlags    queueFlags;
    uint32_t        queueCount;
    uint32_t        timestampValidBits;
    VkExtent3D      minImageTransferGranularity;
} VkQueueFamilyProperties;
  • queueFlags is a bitmask of VkQueueFlagBits= indicating capabilities of the queues in this queue family.

  • queueCount is the unsigned integer count of queues in this = queue family.

  • timestampValidBits is the unsigned integer count of meaning= ful bits in the timestamps written via vkCmdWriteTimestamp. The valid range for the count is 36..64 bits, or a value of 0, indicating no support for timestamps. Bits outside the valid range are guaranteed to be zeros.

  • minImageTransferGranularity is the minimum granularity supp= orted for image transfer operations on the queues in this queue family.

The value returned in minImageTransferGranularity has a uni= t of compressed texel blocks for images having a block-compressed format, and a unit of texels otherwise.

Possible values of minImageTransferGranularity are:

  • (0,0,0) which indicates that only whole mip le= vels must be transferred using the image transfer operations on the corresponding queues. In this case, the following restrictions apply to all offset and extent parameters of image transfer operations:

    • The x, y, and z members of a VkOffset3D parameter must always be zero.

    • The width, height, and depth memb= ers of a VkExtent3D parameter must= always match the width, height, and depth of the image subresource corresponding to the parameter, respectively.

  • (Ax, Ay, Az) = where Ax, Ay, and Az are all integer powers of two. In this case the following restrictions apply to all image transfer operations:

    • x, y, and z of a VkOf= fset3D parameter must be integer multiples of Ax, Ay, and Az, respectively.

    • width of a VkExtent3D parameter must be an integer multiple of Ax, or else x + width m= ust equal the width of the image subresource corresponding to the parameter.

    • height of a VkExtent3D parameter must be an integer multiple of Ay, or else y + height = must equal the height of the image subresource corresponding to the parameter.

    • depth of a VkExtent3D parameter must be an integer multiple of Az, or else z + depth m= ust equal the depth of the image subresource corresponding to the parameter.

    • If the format of the image corresponding to the parameters is one of the block-compressed formats then for the purposes of the above calculations the granularity must be scal= ed up by the compressed texel block dimensions.

Queues supporting graphics and/or compute operations must report (1,1,1) in minImageTransferGranularity, meaning that there are no additional restrictions on the granularity of image transfer operations for these queues. Other queues supporting image transfer operations are only required to support whole mip level transfers, thus minImageTransferGranularity for queues belonging to such queue families may be (0,0,0).

The Device Memory section describes memory properties queried from the physical device.

For physical device feature queries see the Features chapt= er.

Bits which may be set in VkQueueFamilyProperties::queueFlags indicating capabilities of queues in a queue family are:

typedef enum VkQueueFlagBits {
    VK_QUEUE_GRAPHICS_BIT =3D 0x00000001,
    VK_QUEUE_COMPUTE_BIT =3D 0x00000002,
    VK_QUEUE_TRANSFER_BIT =3D 0x00000004,
    VK_QUEUE_SPARSE_BINDING_BIT =3D 0x00000008,
    VK_QUEUE_PROTECTED_BIT =3D 0x00000010,
} VkQueueFlagBits;
  • VK_QUEUE_GRAPHICS_BIT specifies that queues in this queue f= amily support graphics operations.

  • VK_QUEUE_COMPUTE_BIT specifies that queues in this queue fa= mily support compute operations.

  • VK_QUEUE_TRANSFER_BIT specifies that queues in this queue f= amily support transfer operations.

  • VK_QUEUE_SPARSE_BINDING_BIT specifies that queues in this q= ueue family support sparse memory management operations (see Sparse Resources). If any of the sparse resource features are enabled, then at least one queue family must support this bit.

  • if VK_QUEUE_PROTECTED_BIT is set, then the queues in this q= ueue family support the VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT bit. (see Protected Memory). If the protected memory physical device feature is supported, then at least one queue family of at least one physical device exposed by the implementation must support this bit.

If an implementation exposes any queue family that supports graphics operations, at least one queue family of at least one physical device exposed by the implementation must suppor= t both graphics and compute operations.

Furthermore, if the protected memory physical device feature is supporte= d, then at least one queue family of at least one physical device exposed by the implementation must support graphics = operations, compute operations, and protected memory operations.

Note

All commands that are allowed on a queue that supports transfer operatio= ns are also allowed on a queue that supports either graphics or compute operations. Thus, if the capabilities of a queue family include VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT, th= en reporting the VK_QUEUE_TRANSFER_BIT capability separately for that queue= family is optional.

For further details see Queues.

typedef VkFlags VkQueueFlags;

VkQueueFlags is a bitmask type for setting a mask of zero o= r more VkQueueFlagBits.

To query properties of queues available on a physical device, call:

void vkGetPhysicalDeviceQueueFamilyProperties2(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pQueueFamilyPropertyCount,
    VkQueueFamilyProperties2*                   pQueueFamilyProperties);

or the equivalent command

void vkGetPhysicalDeviceQueueFamilyProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pQueueFamilyPropertyCount,
    VkQueueFamilyProperties2*                   pQueueFamilyProperties);
  • physicalDevice is the handle to the physical device whose properties will be queried.

  • pQueueFamilyPropertyCount is a pointer to an integer relate= d to the number of queue families available or queried, as described in vkGetPhysicalDeviceQueueFamilyPro= perties.

  • pQueueFamilyProperties is either NULL or a poi= nter to an array of VkQueueFamilyProperties2 structures.

vkGetPhysicalDeviceQueueFamilyProperties2 behaves similarly= to vkGetPhysicalDeviceQueueFamilyPro= perties, with the ability to return extended information in a pNext chain of output structures.

Valid Usage (Implicit)
  • physicalDevice must be a valid VkPhysicalDevice handle

  • pQueueFamilyPropertyCount must be a valid pointer to a uint32_t = value

  • If the value referenced by pQueueFamilyPropert= yCount is not 0, and pQueueFamilyProperties is not NULL, pQueueFamilyProperties must be a valid pointer to an array of pQueueF= amilyPropertyCount VkQueueFamilyProperties2 structures<= /p>

The VkQueueFamilyProperties2 structure is defined as:

typedef struct VkQueueFamilyPro=
perties2 {
    VkStructureType            sType;
    void*                      pNext;
    VkQueueFamilyProperties    queueFamilyProperties;
} VkQueueFamilyProperties2;

or the equivalent

typedef VkQueueFamilyProperties2 VkQueueFamilyProperties2KHR;<=
/code>
Valid Usage (Implicit)

Additional queue family information can be queried by setting VkQueueFamilyProperties2::pNext = to point to an instance of the VkQueueFamilyCheckpointPropertiesNV structure.

typedef struct VkQueueFamilyChe=
ckpointPropertiesNV {
    VkStructureType         sType;
    void*                   pNext;
    VkPipelineStageFlags    checkpointExecutionStageMask;
} VkQueueFamilyCheckpointPropertiesNV;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • checkpointExecutionStageMask is a mask indicating which pip= eline stages the implementation can execute checkpoint markers in.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE= _TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV

4.2. Devices

Device objects represent logical connections to physical devices. Each device exposes a number of queue families each having one or = more queues. All queues in a queue family support the same operations.

As described in Physical Devices, a Vulkan application will first query for all physical devices= in a system. Each physical device can then be queried = for its capabilities, including its queue and queue family properties. Once an acceptable physical device is identified, an application will creat= e a corresponding logical device. An application must create a separate log= ical device for each physical device it will use. The created logical device is then the primary interface to the physical device.

How to enumerate the physical devices in a system and query those physic= al devices for their queue family properties is described in the Physical Device Enumeration section above.

A single logical device can also be cr= eated from multiple physical devices, if those physical devices belong to the same device group. A device group is a set of physical devices that support accessing= each other=E2=80=99s memory and recording a single command buffer that can be executed on all the physical devices. Device groups are enumerated by calling vkEnumeratePhysicalDeviceGroups, and a= logical device is created from a subset of the physical devices in a device group by passing the physical devices through VkDeviceGroupDeviceCreateInf= o.

To retrieve a list of the device groups present in the system, call:

VkResult vkEnumera=
tePhysicalDeviceGroups(
    VkInstance                                  instance,
    uint32_t*                                   pPhysicalDeviceGroupCount,
    VkPhysicalDeviceGroupProperties*            pPhysicalDeviceGroupPropert=
ies);

or the equivalent command

VkResult vkEnumera=
tePhysicalDeviceGroupsKHR(
    VkInstance                                  instance,
    uint32_t*                                   pPhysicalDeviceGroupCount,
    VkPhysicalDeviceGroupProperties*            pPhysicalDeviceGroupPropert=
ies);
  • instance is a handle to a Vulkan instance previously create= d with vkCreateInstance.

  • pPhysicalDeviceGroupCount is a pointer to an integer relate= d to the number of device groups available or queried, as described below.

  • pPhysicalDeviceGroupProperties is either NULL = or a pointer to an array of VkPhysicalDeviceGroupProperties structures.

If pPhysicalDeviceGroupProperties is NULL, the= n the number of device groups available is returned in pPhysicalDeviceGroupCount. Otherwise, pPhysicalDeviceGroupCount = must point to a variable set by the user to the number of elements in the pPhysicalDeviceGroupProperties array, and on return the variab= le is overwritten with the number of structures actually written to pPhysicalDeviceGroupProperties. If pPhysicalDeviceGroupCount is less than the number of device= groups available, at most pPhysicalDeviceGroupCount structures will b= e written. If pPhysicalDeviceGroupCount is smaller than the number of dev= ice groups available, VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate that not all the available device grou= ps were returned.

Every physical device must be in exact= ly one device group.

Valid Usage (Implicit)
  • <= code>instance must be a valid VkInstance handle

  • pPhysicalDeviceGroupCount must be a valid pointer to a uint32_t value

  • If the value referenced by pPhysicalDeviceGroupC= ount is not 0, and pPhysicalDeviceGroupProperties= is not NULL, pPhysicalDeviceGroupProperties must be a valid pointer to an array of= pPhysicalDeviceGroupCount VkPhysicalDeviceGroupProperti= es structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INITIALIZATION_FAILED

The VkPhysicalDeviceGroupProperties structure is defined as= :

typedef struct VkPhysicalDevice=
GroupProperties {
    VkStructureType     sType;
    void*               pNext;
    uint32_t            physicalDeviceCount;
    VkPhysicalDevice    physicalDevices[VK_MAX_DEVICE_GROUP_SIZE];
    VkBool32            subsetAllocation;
} VkPhysicalDeviceGroupProperties;

or the equivalent

typedef VkPhysicalDeviceGroupProperties VkPhysicalDeviceGroupP=
ropertiesKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • physicalDeviceCount is the number of physical devices in th= e group.

  • physicalDevices is an array of physical device handles representing all physical devices in the group. The first physicalDeviceCount elements of the array will be va= lid.

  • subsetAllocation specifies whether logical devices created = from the group support allocating device memory on a subset of devices, via the deviceMask member of the VkMemo= ryAllocateFlagsInfo. If this is VK_FALSE, then all device memory allocations are ma= de across all physical devices in the group. If physicalDeviceCount is 1, then subsetAll= ocation must be VK_FALSE.

4.2.1. Device Creation

Logical devices are represented by VkDevice handles:

VK_DEFINE_HANDLE(V=
kDevice)

A logical device is created as a connection to a physical devic= e. To create a logical device, call:

VkResult vkCreateD=
evice(
    VkPhysicalDevice                            physicalDevice,
    const VkDeviceCreateInfo*             =
      pCreateInfo,
    const VkAllocationCallbacks*          =
      pAllocator,
    VkDevice*                                   pDevice);
  • physicalDevice must be on= e of the device handles returned from a call to vkEnumeratePhysicalDevices (see Physical Device Enumeration).

  • pCreateInfo is a pointer to a VkDeviceC= reateInfo structure containing information about how to create the device.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

  • pDevice points to a handle in which the created V= kDevice is returned.

vkCreateDevice verifies that extensions and features reques= ted in the ppEnabledExtensionNames and pEnabledFeatures memb= ers of pCreateInfo, respectively, are supported by the implementation= . If any requested extension is not supported, vkCreateDevice must return VK_ERROR_EXTENSION_NOT_PRESENT. If any requested feature is not supported, vkCreateDevice must return VK_ERROR_FEATURE_NOT_PRESENT. Support for extensions can be checked bef= ore creating a device by querying vkEnumerateDeviceExtensionProperties<= /a>. Support for features can similarly be che= cked by querying vkGetPhysicalDeviceFeatures.

After verifying and enabling the extensions the VkDevice ob= ject is created and returned to the application. If a requested extension is only supported by a layer, both the layer and the extension need to be specified at vkCreateInstance time fo= r the creation to succeed.

Multiple logical devices can be create= d from the same physical device. Logical device creation may fail due to l= ack of device-specific resources (in addition to the other errors). If that occurs, vkCreateDevice will return VK_ERROR_TOO_MANY_OBJECTS.

Valid Usage
Valid Usage (Implicit)
  • physic= alDevice must be a valid VkP= hysicalDevice handle

  • pCreateIn= fo must be a valid pointer to a va= lid VkDeviceCreateInfo structure

  • If pAlloca= tor is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

  • pDevice must be a valid pointer to a VkDe= vice handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INITIALIZATION_FAILED

  • VK_ERROR_EXTENSION_NOT_PRESENT

  • VK_ERROR_FEATURE_NOT_PRESENT

  • VK_ERROR_TOO_MANY_OBJECTS

  • VK_ERROR_DEVICE_LOST

The VkDeviceCreateInfo structure is defined as:

typedef struct VkDeviceCreateIn=
fo {
    VkStructureType                    sType;
    const void*                        pNext;
    VkDeviceCreateFlags                flags;
    uint32_t                           queueCreateInfoCount;
    const VkDeviceQueueCreateInfo*     pQu=
eueCreateInfos;
    uint32_t                           enabledLayerCount;
    const =
char* const*                 ppEnab=
ledLayerNames;
    uint32_t                           enabledExtensionCount;
    const =
char* const*                 ppEnab=
ledExtensionNames;
    const VkPhysicalDeviceFeatures*    pEn=
abledFeatures;
} VkDeviceCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is reserved for future use.

  • queueCreateInfoCount is the unsigned integer size of the pQueueCreateInfos array. Refer to the Queue Creation section below for further details.

  • pQueueCreateInfos is a pointer to an array of VkDeviceQueueCreateInfo structures describing = the queues that are requested to be created along with the logical device. Refer to the Queue Creation section below for further details.

  • enabledLayerCount is deprecated and ignored.

  • ppEnabledLayerNames is deprecated and ignored. See Device Layer Deprecation.

  • enabledExtensionCount is the number of device extensions to enable.

  • ppEnabledExtensionNames is a pointer to an array of enabledExtensionCount null-terminated UTF-8 strings containing= the names of extensions to enable for the created device. See the Extensions section for further details.

  • pEnabledFeatures is NULL or a pointer to a VkPhysicalDeviceFeatures structure that conta= ins boolean indicators of all the features to be enabled. Refer to the Features section for further details.

Valid Usage
  • The queueFamilyIndex member of each element of pQueueCreateInfos must be un= ique within pQueueCreateInfos, except that two members can share the same queueFamilyIndex if= one is a protected-capable queue and one is not a protected-capable queue.

  • If the pNext chain includes a VkPhy= sicalDeviceFeatures2 structure, then pEnabledFeatures must= be NULL

  • ppEnabledExtensionNames must= not contain VK_AMD_negative_viewport_height

Valid Usage (Implicit)
typedef VkFlags VkDeviceCreateFlags;

VkDeviceCreateFlags is a bitmask type for setting a mask, b= ut is currently reserved for future use.

A logical device can be created that c= onnects to one or more physical devices by including a VkDeviceGroupDeviceCreateInfo structure= in the pNext chain of VkDeviceCreateInfo. The VkDeviceGroupDeviceCreateInfo structure is defined as:

typedef struct VkDeviceGroupDev=
iceCreateInfo {
    VkStructureType            sType;
    const void*                pNext;
    uint32_t                   physicalDeviceCount;
    const VkPhysicalDevice*    pPhysicalDe=
vices;
} VkDeviceGroupDeviceCreateInfo;

or the equivalent

typedef VkDeviceGroupDeviceCreateInfo VkDeviceGroupDeviceCreat=
eInfoKHR;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • physicalDeviceCount is the number of elements in the pPhysicalDevices array.

  • pPhysicalDevices is an array of physical device handles bel= onging to the same device group.

The elements of the pPhysicalDevices array are an ordered l= ist of the physical devices that the logical device represents. These must be a subset of a single device= group, and need not be in the same order as they were enumerated. The order of the physical devices in the pPhysicalDevices arra= y determines the device index of each physical device, with element = i being assigned a device index of i. Certain commands and structures refer to one or more physical devices by using device indices or device masks formed using device indices.<= /p>

A logical device created without using VkDeviceGroupDeviceCreateIn= fo, or with physicalDeviceCount equal to zero, is equivalent to a physicalDeviceCount of one and pPhysicalDevices p= ointing to the physicalDevice parameter to vkCreateDevice= . In particular, the device index of that physical device is zero.

Valid Usage
Valid Usage (Implicit)
  • sTyp= e must be VK_STRUCTURE_TYPE_= DEVICE_GROUP_DEVICE_CREATE_INFO

  • = If physicalDeviceCount is not 0, pPhys= icalDevices must be a valid pointe= r to an array of physicalDeviceCount valid VkPhysicalDev= ice handles

4.2.2. Device Use

The following is a high-level list of VkDevice uses along w= ith references on where to find more information:

4.2.3. Lost Device

A logical device may become lost for a number of implementation-specific reasons, indicating that pending and future command execution may fail and cause resources and backing memory to become undefined.

Note

Typical reasons for device loss will include things like execution timin= g out (to prevent denial of service), power management events, platform resource management, or implementation errors.

When this happens, certain commands will return VK_ERROR_DEVICE_LO= ST (see Error Codes for a list of such commands). After any such event, the logical device is considered lost. It is not possible to reset the logical device to a non-lost state, however the lost state is specific to a logical device (VkDevice), and= the corresponding physical device (VkPhysicalDevice) may be otherwise unaffected.

In some cases, the physical device may= also be lost, and attempting to create a new logical device will fail, returning VK_ERROR_DEVICE_LOST= . This is usually indicative of a problem with the underlying implementation, or its connection to the host. If the physical device has not been lost, and a new logical device is successfully created from that physical device, it must be in the non-lost state.

Note

Whilst logical device loss may be reco= verable, in the case of physical device loss, it is unlikely that an application will be able to recover unless additional, unaffected physical devices exist on the system. The error is largely informational and intended only to inform the user tha= t a platform issue has occurred, and should= be investigated further. For example, underlying hardware may have= developed a fault or become physically disconnected from the rest of the system. In many cases, physical device loss may c= ause other more serious issues such as the operating system crashing; in which case it may not be reported via the Vulkan API.

Note

Undefined behavior caused by an application error may cause a device to become lost. However, such undefined behavior may also= cause unrecoverable damage to the process, and it is then not guaranteed that the API objects, including the VkPhysicalDevice or the VkInstance are still vali= d or that the error is recoverable.

When a device is lost, its child objects are not implicitly destroyed an= d their handles are still valid. Those objects must still be destroyed bef= ore their parents or the device can be destroyed (see the Object Lifetime section). The host address space corresponding to device memory mapped using vkMapMemory is still valid, and host memory accesses to th= ese mapped regions are still valid, but the contents are undefined. It is still legal to call any API command on the device and child objects.<= /p>

Once a device is lost, command execution may fail, and commands that return a VkResult may return VK_ERROR_DEVICE_LOST. Commands that do not allow run-time errors must still operate correctly for valid usage and, if applicable, return valid data.

Commands that wait indefinitely for device execution (namely vkDeviceWaitIdle, vkQueueWaitIdle, vkWaitForFences or vkAcquireNextImageKHR with a maximum timeout, and vkGetQueryP= oolResults with the VK_QUERY_RESULT_WAIT_BIT bit set in flags) must return in finite time even in the case of a lost device, and return either VK_SUCCESS or VK_ERROR_DEVICE_LOST. For any command that may return VK_= ERROR_DEVICE_LOST, for the purpose of determining whether a command buffer is in the pending state, or whether resources are considered in-use by the device, a return value of VK_ERROR_DEVICE_LOST is equivalent to VK_SUCCESS.=

The content of any external memory objects that have been exported from = or imported to a lost device become undefined. Objects on other logical devices or in other APIs which are associated with the same underlying memory resource as the external memory objects on the lost device are unaffected other than their content becoming undefined. The layout of subresources of images on other logical devices that are boun= d to VkDeviceMemory objects associated with the same underlying = memory resources as external memory objects on the lost device becomes VK_IMAGE_LAYOUT_UNDEFINED.

The state of VkSemaphore objects on other logical devices c= reated by importing a semaphore payload wit= h temporary permanence which was exported from the lost device is undefined. The state of VkSemaphore objects on other logical devices that permanently share a semaphore payload with a VkSemaphore objec= t on the lost device is undefined, and remains undefined following any subsequent signal operations. Implementations must ensure pending and s= ubsequently submitted wait operations on such semaphores behave as defined in Semaphore State Requirements For Wait Operations for external semaphores not in a valid state for a wait operation.

editing-note

TODO (piman) - I do not think we are very clear about what =E2=80=9Cin-u= se by the device=E2=80=9D means.

4.2.4. Device Destruction

To destroy a device, call:

void vkDestroyDevice(
    VkDevice                                    device,
    const VkAllocationCallbacks*          =
      pAllocator);
  • device is the logical device to destroy.

  • pAllocator controls host memory allocation as described in = the Memory Allocation chapter.

To ensure that no work is active on the device, vkDevi= ceWaitIdle can be used to gate the destruction of the device. Prior to destroying a device, an application is responsible for destroying/freeing any Vulkan objects that were created using that device a= s the first parameter of the corresponding vkCreate* or vkAllocate* command.

Note

The lifetime of each of these objects is bound by the lifetime of the VkDevice object. Therefore, to avoid resource leaks, it is critical that an application explicitly free all of these resources prior to calling vkDestroyDevice.

Valid Usage
  • All child objects created on device m= ust have been destroyed prior to destroying device

  • If VkAllocationCallbacks were provided when device was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when device was created, pAllocator must be = NULL

Valid Usage (Implicit)
  • If device is not NULL, device = must be a valid VkDevice handle

  • If pAlloc= ator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationC= allbacks structure

Host Synchronization
  • Host access to device must be externally synchronized

4.3. Queues

4.3.1. Queue Family Properties

As discussed in the Physical Device Enumeration section above, the vkGetPhysicalDeviceQueueFamilyPro= perties command is used to retrieve details about the queue families and queues supported by a device.

Each index in the pQueueFamilyProperties array returned by vkGetPhysicalDeviceQueueFamilyPro= perties describes a unique queue family on that physical device. These indices are used when creating queues, and they correspond directly with the queueFamilyIndex that is passed to the VkDeviceQueueCreateInfo struct= ure as described in the Queue Creation section below.

Grouping of queue families within a physical device is implementation-dependent.

Note

The general expectation is that a physical device groups all queues of matching capabilities into a single family. However, while implementations should do = this, it is possible that a physical device may return two separate q= ueue families with the same capabilities.

Once an application has identified a physical device with the queue(s) t= hat it desires to use, it will create those queues in conjunction with a logica= l device. This is described in the following section.

4.3.2. Queue Creation

Creating a logical device also creates the queues associated with that device. The queues to create are described by a set of VkD= eviceQueueCreateInfo structures that are passed to vkCreateDevice in pQueueCreateInfos.

Queues are represented by VkQueue handles:

VK_DEFINE_HANDLE(V=
kQueue)

The VkDeviceQueueCreateInfo structure is defined as:

typedef struct VkDeviceQueueCre=
ateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkDeviceQueueCreateFlags    flags;
    uint32_t                    queueFamilyIndex;
    uint32_t                    queueCount;
    const =
float*                pQueuePriorities;
} VkDeviceQueueCreateInfo;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • flags is a bitmask indicating behavior of the queue.

  • queueFamilyIndex is an unsigned integer indicating the inde= x of the queue family to create on this device. This index corresponds to the index of an element of the pQueueFamilyProperties array that was returned by vkGetPhysicalDeviceQueueFamilyProperties.

  • queueCount is an unsigned integer specifying the number of = queues to create in the queue family indicated by queueFamilyIndex.

  • pQueuePriorities is an array of queueCount nor= malized floating point values, specifying priorities of work that will be submitted to each created queue. See Queue Priority for more information.

Valid Usage
  • queueFamilyIndex must be les= s than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties

  • queueCount must be less than= or equal to the queueCount member of the VkQueueFamilyProperties structure, as returned b= y vkGetPhysicalDeviceQueueFamilyProperties in the pQueueFamilyProperties[queueFamilyIndex]

  • Each element of pQueuePriorities must= be between 0.0 and 1.0 inclusive

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEVICE= _QUEUE_CREATE_INFO

  • pNext must be NULL or a pointer= to a valid instance of VkDeviceQ= ueueGlobalPriorityCreateInfoEXT

  • flags<= /code> must be a valid combination of VkDeviceQueueCreateFlagBits values

  • <= code>pQueuePriorities must be a va= lid pointer to an array of queueCount float value= s

  • queueCount must be greater than <= code>0

Bits which can be set in VkDeviceQueueCreateInfo::flags to specify usage behavior of the queue are:

typedef enum VkDeviceQueueCreat=
eFlagBits {
    VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT =3D 0x00000001=
,
} VkDeviceQueueCreateFlagBits;
  • VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT specifies that the dev= ice queue is a protected-capable queue. If the protected memory feature is not enabled, the VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT bit of flags= must not be set.

typedef VkFlags VkDeviceQueueCreateFlags;

VkDeviceQueueCreateFlags is a bitmask type for setting a ma= sk of zero or more VkDeviceQueueCreateFlagBits.

A queue can be created with a system-w= ide priority by including a VkDeviceQueueGlobalPriorityCreateInfoEXT structure in the pNext chain of VkDeviceQueueCreateInfo.

The VkDeviceQueueGlobalPriorityCreateInfoEXT structure is d= efined as:

typedef struct VkDeviceQueueGlo=
balPriorityCreateInfoEXT {
    VkStructureType             sType;
    const void*                 pNext;
    VkQueueGlobalPriorityEXT    globalPriority;
} VkDeviceQueueGlobalPriorityCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure.

  • globalPriority is the system-wide priority associated to th= is queue as specified by VkQueueGlobalPriorityEXT

A queue created without specifying VkDeviceQueueGlobalPriorityCreateInfoEXT will default to VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT.

Valid Usage (Implicit)
  • = sType must be VK_STRU= CTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT

  • globalPriority must be a valid VkQueueGlobalPriorityEXT val= ue

Possible values of VkDeviceQueueGlobalPriorityCreate= InfoEXT::globalPriority, specifying a system-wide priority level are:

typedef enum VkQueueGlobalPrior=
ityEXT {
    VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT =3D 128=
,
    VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT =3D 256,
    VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT =3D 512,
    VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT =3D 1024<=
/span>,
} VkQueueGlobalPriorityEXT;

Priority values are sorted in ascending order. A comparison operation on the enum values can be used to determine the priority order.

  • VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT is below the system defaul= t. Useful for non-interactive tasks.

  • VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT is the system default priority.

  • VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT is above the system defau= lt.

  • VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT is the highest priori= ty. Useful for critical tasks.

Queues with higher system priority may= be allotted more processing time than queues with lower priority. An implementation may allow a higher-prio= rity queue to starve a lower-priority queue until the higher-priority queue has no further command= s to execute.

Priorities imply no ordering or scheduling constraints.

No specific guarantees are made about higher priority queues receiving m= ore processing time or better quality of service than lower priority queues.

The global priority level of a queue takes precedence over the per-proce= ss queue priority (VkDeviceQueueCreateInfo::pQueuePrioritie= s).

Abuse of this feature may result in st= arving the rest of the system of implementation resources. Therefore, the driver implementation may = deny requests to acquire a priority above the default priority (VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT) if the caller does not h= ave sufficient privileges. In this scenario VK_ERROR_NOT_PERMITTED_EXT is returned.

The driver implementation may fail the= queue allocation request if resources required to complete the operation have been exhausted (either by the same process or a different process). In this scenario VK_ERROR_INITIALIZATION_FAILED is returned.

To retrieve a handle to a VkQueue object, call:

void vkGetDeviceQueue(
    VkDevice                                    device,
    uint32_t                                    queueFamilyIndex,
    uint32_t                                    queueIndex,
    VkQueue*                                    pQueue);
  • device is the logical device that owns the queue.

  • queueFamilyIndex is the index of the queue family to which = the queue belongs.

  • queueIndex is the index within this queue family of the que= ue to retrieve.

  • pQueue is a pointer to a VkQueue object that w= ill be filled with the handle for the requested queue.

vkGetDeviceQueue must onl= y be used to get queues that were created with the flags parameter of VkDeviceQueueCreateInfo set to zero. To get queues that were created with a non-zero flags paramete= r use vkGetDeviceQueue2.

Valid Usage
  • queueFamilyIndex must be one= of the queue family indices specified when device was created, via the VkDeviceQueueCreateInfo structure

  • queueIndex must be less than= the number of queues created for the specified queue family index when device was created, via the queueCount member of the VkDeviceQueueCreateInfo = structure

  • VkDeviceQueueCreateInfo::flags must have been set to zero when device was created

Valid Usage (Implicit)
  • device must be a valid VkDevice h= andle

  • pQueue must be a valid pointer to a VkQu= eue handle

To retrieve a handle to a VkQueue object with specific VkDeviceQueueCreateFlags creation flags, call:

void vkGetDeviceQueue2(
    VkDevice                                    device,
    const VkDeviceQueueInfo2*             =
      pQueueInfo,
    VkQueue*                                    pQueue);
  • device is the logical device that owns the queue.

  • pQueueInfo points to an instance of the VkDeviceQueueInfo2 structure, describing the parameters used to create the device queue.

  • pQueue is a pointer to a VkQueue object that w= ill be filled with the handle for the requested queue.

Valid Usage (Implicit)
  • device must be a valid VkDevice = handle

  • pQueueI= nfo must be a valid pointer to a v= alid VkDeviceQueueInfo2 structure

  • pQueue must be a valid pointer to a VkQ= ueue handle

The VkDeviceQueueInfo2 structure is defined as:

typedef struct VkDeviceQueueInf=
o2 {
    VkStructureType             sType;
    const void*                 pNext;
    VkDeviceQueueCreateFlags    flags;
    uint32_t                    queueFamilyIndex;
    uint32_t                    queueIndex;
} VkDeviceQueueInfo2;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-spe= cific structure. The pNext chain of VkDeviceQueueInfo2 is used to = provide additional image parameters to vkGetDeviceQueue2.

  • flags is a VkDeviceQueueCreateFla= gs value indicating the flags used to create the device queue.

  • queueFamilyIndex is the index of the queue family to which = the queue belongs.

  • queueIndex is the index within this queue family of the que= ue to retrieve.

The queue returned by vkGetDeviceQueue2 must have the same flags value from this structure as that used at device creatio= n time in a VkDeviceQueueCreateInfo instance. If no matching flags were specified at device creation time th= en pQueue will return VK_NULL_HANDLE.

Valid Usage
  • queueFamilyIndex must be one= of the queue family indices specified when device was created, via the VkDeviceQueueCreateInfo structure

  • queueIndex must be less than= the number of queues created for the specified queue family index and VkDeviceQueueCreateFlags memb= er flags equal to this flags value when device= was created, via the queueCount member of the VkDeviceQueueCreateInfo structure

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEVICE_QUEU= E_INFO_2

  • pNext must be NULL

  • flags must be a valid combination of VkDeviceQueueCreateFlagBits values

  • flags= must not be 0

4.3.3. Queue Family Index

The queue family index is used in multiple places in Vulkan in order to = tie operations to a specific family of queues.

When retrieving a handle to the queue via vkGetDeviceQueue,= the queue family index is used to select which queue family to retrieve the VkQueue handle from as described in the previous section.

When creating a VkCommandPool object (see Command Pools), a queue family index is specified in the VkCommandPoolCreateInfo structure. Command buffers from this pool can only b= e submitted on queues corresponding to this queue family.

When creating VkImage (see Images) an= d VkBuffer (see Buffers) resources, a set= of queue families is included in the VkImageCreateInfo and VkBufferCreateInfo structures to specify the queue = families that can access the resource.

When inserting a VkBufferMemoryBarrier or VkImageMemoryBarrier (see Events) a source and destination queue fam= ily index is specified to allow the ownership of a buffer or image to be transferred from one queue family to another. See the Resource Sharing section for details.

4.3.4. Queue Priority

Each queue is assigned a priority, as set in the VkDeviceQueueCreateInfo structures when creati= ng the device. The priority of each queue is a normalized floating point value between 0.0 and 1.0, which is then translated to a discrete priority level by the implementation. Higher values indicate a higher priority, with 0.0 being the lowest priorit= y and 1.0 being the highest.

Within the same device, queues with higher priority may be allotted more processing time than queues with lower priority. The implementation makes no guarantees with regards to ordering or scheduling among queues with the same priority, other than the constraints defined by any explicit synchronization primitives. The implementation make no guarantees with regards to queues across different devices.

An implementation may allow a higher-p= riority queue to starve a lower-priority queue on the same VkDevice until the higher-pri= ority queue has no further commands to execute. The relationship of queue priorities must= not cause queues on one VkDevice to starve queues on another VkDevice.

No specific guarantees are made about higher priority queues receiving m= ore processing time or better quality of service than lower priority queues.

4.3.5. Queue Submission

Work is submitted to a queue via queue submission commands such= as vkQueueSubmit. Queue submission commands define a set of queue operations to be e= xecuted by the underlying physical device, including synchronization with semaphore= s and fences.

Submission commands take as parameters a target queue, zero or more batches of work, and an optional= fence to signal upon completion. Each batch consists of three distinct parts:

  1. Zero or more semaphores to wait on before execution of the rest of the batch.

  2. Zero or more work items to execute.

    • If present, these describe a queue operation matching the work described.

  3. Zero or more semaphores to signal upon completion of the work items.

If a fence is present in a queue submission, it describes a fence signal operation.

All work described by a queue submission command must be submitted to the queue before the command returns.

Sparse Memory Binding

In Vulkan it is possible to sparsely bind memory to buffers and images a= s described in the Sparse Resource chapter. Sparse memory binding is a queue operation. A queue whose flags include the VK_QUEUE_SPARSE_BINDING_BIT must be able to support the mapping of a virtual address to a physical address on the device. This causes an update to the page table mappings on the device. This update must be synchronized on a que= ue to avoid corrupting page table mappings during execution of graphics commands. By binding the sparse memory resources on queues, all commands that are dependent on the updated bindings are synchronized to only execute after th= e binding is updated. See the Synchronization and Cache Control chapter for how this synchronization is accomplished.

4.3.6. Queue Destruction

Queues are created along with a logical device during vkCreateDevi= ce. All queues associated with a logical device are destroyed when vkDestroyDevice is called on that device.